LoginSignup
26
12

More than 3 years have passed since last update.

【解説付き】Django チュートリアル その2 -前編-

Last updated at Posted at 2019-08-16

はじめに

これは、【解説付き】Django チュートリアル その1に続き、
はじめての Django アプリ作成、その2に解説をつけて初学者にわかりやすく学んでいただきたいというためのものです。

その2は、ボリュームがあるため前編/後編とさせていただいております。

対象

  • pythonはなんとなくわかってるけど、djangoを覚えたい
  • 業務でdjango触ってたけど、きちんと理解したい

上記の方々を対象としています。
環境は、Macを使用して進めていきますので、Windowsユーザーの方は、Windows環境に読み替えてついてきていただければと思います。

目次

settings.py

mysite/settings.py を見ていきましょう
これは、 Django の設定を管理するための Pythonファイルです。

INSTALLED_APPSの設定

INSTALLED_APPS は、Djangoインスタンスの中で有効化したいDjangoアプリケーションの名前を記載します。
pip installなどで、個別に追加するアプリケーションもここに追加していくことになります。

mysite/settings.py
...
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
...

デフォルトでは、 よく利用される下記のアプリケーションが、INSTALLED_APPS に指定されています。

  • django.contrib.admin - 管理(admin)サイト。後ほど説明します。
  • django.contrib.auth - 認証システム
  • django.contrib.contenttypes - コンテンツタイプフレームワーク
  • django.contrib.sessions - セッションフレームワーク
  • django.contrib.messages - メッセージフレームワーク
  • django.contrib.staticfiles - 静的ファイルの管理フレームワーク

これらのアプリケーションはデータベースを使用するため、事前にデータベース内にテーブルを作る必要があります。
こちらは後ほど説明します。

Databaseの設定

デフォルトの設定では SQLite が指定されています。
データベースに詳しくなかったり、Django を試してみたいだけなら、SQLiteのままで進めましょう。
SQLitePython に標準で組み込まれているため、接続するために何もインストールする必要がありません。
本番環境で使う場合には、AWSGCPでも提供されているPostgreSQLMySQL などのデータベースが良いでしょう。

公式のチュートリアルでは、PostgreSQLを使用しています。

mysite/settings.py
...

# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

# デフォルトのままの、SQLiteの例
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

...

他のデータベースを使いたい場合、データベースと接続するモジュール(mysql client等)をインストールして、
settings.py内にある、DATABASESdefault項目内の以下のキーをデータベースの接続設定に合うように変更してください。

  • ENGINE
    'django.db.backends.sqlite3''django.db.backends.postgresql''django.db.backends.mysql' または 'django.db.backends.oracle' のいずれかにします。
    ※その他のバックエンド も利用可能です。

  • NAME
    データベースの名前です。
    SQLite を使用している場合、データベースはコンピュータ上のファイルになります。
    その場合、NAME には、そのファイルのファイル名を含んだ絶対パスを指定する必要があります。
    デフォルト値は os.path.join(BASE_DIR, 'db.sqlite3') で、ファイルはプロジェクトのディレクトリに保存されます。

SQLite 以外を使う場合、 データベースに接続するための、USERPASSWORD そして HOST などの追加設定を加える必要があります。
※詳細については DATABASES のリファレンスドキュメントを参照してください。

TIME_ZONE の設定

mysite/settings.py で、 タイムゾーンを指定する事ができます。

mysite/settings.py
TIME_ZONE = 'UTC'

USE_TZ = True
  • TIME_ZONE: TIME_ZONEの指定により、テンプレートで出力される日時情報が変換して出力されます
  • USE_TZ: フォームの日付入力欄で、入力した日付が変換されます

※タイムゾーン関連は複雑なため、別途記事にまとめるのでここで詳細は割愛します。

migrateコマンドを実行する

ここまで設定した内容だけでは、INSTALLED_APPSの機能を使うことはできません。
前述した通り、データベースにテーブルが必要です。

マイグレーションファイルから、テーブルを自動的に作成してくれるmigrateコマンドを実行してみましょう
※マイグレーションファイルについては、この先で触れていきます。

$ python manage.py migrate

migrate コマンドは INSTALLED_APPS に記載されている情報を元に、必要なテーブルを作成します。

※マイグレーションファイルはアプリケーション内に内包されています。

Djangoが作成したテーブルを、確認したい場合は、データベース毎のコマンドで確認できます。

データベースのクライアント上で、

  • \dt (PostgreSQL)
  • SHOW TABLES; (MySQL)
  • .schema (SQLite)
  • SELECT TABLE_NAME FROM USER_TABLES; (Oracle)

と入力してみましょう。

Model

Modelとは

Modelには、データベースの定義と、それに付随するMETAデータをクラスとして記述します。

Modelの作成

これから開発する polls アプリケーションでは、投票項目 (Question)選択肢 (Choice) の二つのモデルを作成します。
Question には「質問事項 (question)」と「公開日 (publication date)」 の情報があります。
Choice には「選択肢のテキスト」と「投票数 (vote)」 という二つのフィールドがあります。
Choiceデータは、Question に関連づけられるone to manyとなります。

Django では、こうした概念を簡単な Python クラスで表現できます。
polls/models.py ファイルを以下のように編集してください。

polls/models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    # Questionに対してリレーションを貼る
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

Model(テーブル)はdjango.db.models.Modelを継承して、クラスを作ります。
クラスは、テーブルの定義、
クラス変数は、テーブルのカラムの定義となります。

Modelフィールド

各フィールドは Field クラスのインスタンスとして表現されています。
例えば、 CharField は文字のフィールド(カラム)で、 DateTimeField は日時のフィールド(カラム)です。

フィールド名(verbose)

Field の最初の引数には、フィールド名を指定できます。(省略可能)

    question_text = models.CharField("question's text", max_length=200)

指定しない場合は、question_textのアンダースコアをスペースに置き換えたquestion textとなります。

上の例の、Question.pub_date'date published'もフィールド名となります。

フィールドのパラメータ(引数)

Field クラスの中には必須の引数を持つものがあります。
例えば CharField には max_length を指定する必要があります。
この引数はデータベースの定義で使われる他、バリデーションでも使われます。(後ほど説明)

Field には、オプションの引数もあります。
上記の場合、 Choice.votes の default の値を 0 に設定しました。
これは、Choiceデータを作成する際に、Choice.votesの値が指定されていなければ、「0を設定する」という意味です。

ForeignKey(リレーション)

polls/models.py

class Question(models.Model):
    ...


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    ...

ForeignKeyを使用して、リレーションを定義することができます。
これは、ChoiceQuestionに関連付けられること意味します。
Django では 多対一(many to one)多対多(many to many)、そして一対一(one to one)のようなデータベースリレーションシップすべてをサポートします。

今回の構造だと下記のようなテーブルとなります。

Questionテーブル

id question_text pub_date
1 好きな食べものは何ですか? 2019-08-16 00:00:00

Choiceテーブル

id question_id choice_text votes
1 1 和食 0
2 1 洋食 0
3 1 イタリアン 0

プロジェクトにアプリケーション(パッケージ)を追加する

この段階では、プロジェクトがpollsアプリケーションを認識できていません。

pollsをプロジェクトに追加させることで、
前述したModelファイルを使って、アプリケーションのデータベーススキーマ(migrateファイル)を作成 (CREATE TABLE 文を実行) できます。

アプリケーションを認識させるには、settings.pyINSTALLED_APPSに追加する必要があります。

PollsConfigクラスは、 polls/apps.pyにあるので、指定する記述は'polls.apps.PollsConfig'となります。

下記のようにmysite/settings.py を編集し、 INSTALLED_APPSに上記のパスを追加します。

mysite/settings.py
...
INSTALLED_APPS = [
    # pollsパッケージの追加
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    ...
]
...

これで Django は、pollsアプリケーションを認識することができます。

migrate

※チュートリアル通した後に見返すくらいでも良いかもしれません。軽く読み進めたい人はmigrateのポイントに進めてもらって大丈夫です。

makemigrationsコマンドを使って、マイグレーションファイルを作成します。

マイグレーションファイル ・・・データベースを作成・変更するためのスキーマの定義情報

$ python manage.py makemigrations polls

コマンドが成功すると、下記のようなメッセージが出力されます
(選択しているデータベースにより若干メッセージは変わります)

Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice

makemigrations を実行すると、Modelの変更内容(この場合、新しいものを作成しました)を、マイグレーションファイルとして生成されます。

マイグレーションはモデル(と、データベーススキーマ情報)の変更をファイルとして保存する方法です。
生成されたマイグレーションをファイル polls/migrations/0001_initial.py は、ファイルを開いて確認することもできます。
マイグレーションのファイルを作成するたびに、毎回読む必要はありません。
ですが、マイグレーションの変更内容を微調整したいという時は、修正も可能です。

Django には、マイグレーションを自動的に実行し、データベーススキーマを更新・管理するためのコマンドがあります。これは migrate と呼ばれるコマンドで、この後すぐに見ていきます。
その前に、マイグレーションがどんなSQLを実行するのか見てみましょう。
sqlmigrate コマンドはマイグレーションの名前を指定し、実行されるSQLを出力します。

$ python manage.py sqlmigrate polls 0001

次のような結果が表示されます。

チュートリアルのPostgreSQLの出力
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;

COMMIT;
SQLiteの出力

BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "question_text" varchar(200) NOT NULL, 
    "pub_date" datetime NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "choice_text" varchar(200) NOT NULL, 
    "votes" integer NOT NULL, 
    "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED
);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;

以下のポイントを覚えておいてください

  • sqlmigrateの出力は、使用しているデータベースによって異なります。
  • テーブル名はアプリケーションの名前 (polls) とモデルの小文字表記 の questionchoice を組み合わせて、polls_questionpolls_choiceのように自動的に生成されます。 (指定することも可能です)
  • 主キー (primary key, ID) は自動的に追加されます (この挙動もオーバライド可能です)。
  • Django は外部キーのフィールド名に "_id"(今回はquestion_id) を追加します。(指定することも可能です)
  • 外部キーリレーションシップは FOREIGN KEY 制約で明確化されます。 DEFERRABLE の部分については心配しないでください。 PostgreSQLに外部キーをトランザクション終了まで強制しないようにするためのものです。
  • 使用するデータベースに合わせて、auto_increment (MySQL)serial (PostgreSQL) もしくは integer primary key autoincrement (SQLite) のようなデータベース固有の型が自動的に選択され生成されます。フィールド名のクォーティング (例えば、ダブルクォートにするか、シングルクォートにするか) も同様です。
  • sqlmigrate コマンドはデータベースにマイグレーションは実行されません。実行されるSQLが何であるかをスクリーンに表示するだけです。これはDjangoが何をしようとしているかを確認したり、データベース管理者に変更のためのSQLスクリプトを要求されているときに役に立ちます。

もし興味があれば python manage.py check を実行することもできます。 これはマイグレーションを作成したりデータベースに影響なく、プロジェクトに何か問題がないか確認します 。

migrate を再度実行し、 Modelで定義したテーブルを作成しましょう。

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK

migrate コマンドは、未適応のマイグレーションファイルを探索し、データベースに対して実行していきます。
重要なのは、モデルに対して行った変更はデータベースのスキーマに同期するということです。

(Djangoはデータベース内の django_migrations テーブルを利用して、マイグレーションの変更履歴を管理しています。)

migrateのポイント

今の段階では、Modelの変更を実施するための3ステップガイドを覚えておいてください
(最低限、ここだけ押さえておけば、問題ないと思います)

  • Modelを変更する (models.py のクラスを修正)
  • 変更状態のマイグレーションファイルを作成するために python manage.py makemigrations を実行します。
  • データベースに変更を適用するために python manage.py migrate を実行します。

マイグレーションの作成と適用のコマンドが分割されている理由は、マイグレーションをバージョン管理システムにコミットし、アプリとともに配布するためです。これによって、あなたの開発が容易になるだけでなく、他の開発者や本番環境にとって使いやすいものになります。

まとめ

ここまでがdjango チュートリアルのその2 -前編- でした。

既にdjangoに触れてる人や、多言語に詳しい人ならわかるけど、初めての人にはわかりにくい部分が多いと思います。
データベースやテーブルなど、初学者には壁となるポイントが出てくるかと思います。
まずは、ここでの理解は無くても良いので、先に進めてみてください。

チュートリアルやドキュメントは何度も読み返して知識を積み重ねていければ良いと思います。

次は、【解説付き】Django チュートリアル その2 -後編-に読み進めてもらえると幸いです。



[PR]
長方形-システム開発002.png

26
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
12