はじめに
これは、【解説付き】Django チュートリアル その1に続き、
はじめての Django アプリ作成、その2に解説をつけて初学者にわかりやすく学んでいただきたいというためのものです。
その2は、ボリュームがあるため前編/後編とさせていただいております。
対象
- pythonはなんとなくわかってるけど、djangoを覚えたい
- 業務でdjango触ってたけど、きちんと理解したい
上記の方々を対象としています。
環境は、Macを使用して進めていきますので、Windowsユーザーの方は、Windows環境に読み替えてついてきていただければと思います。
目次
- 【解説付き】Django チュートリアル その1
- 【解説付き】Django チュートリアル その2 -前編-
- 【解説付き】Django チュートリアル その2 -後編-
settings.py
mysite/settings.py
を見ていきましょう
これは、 Django の設定を管理するための Pythonファイルです。
INSTALLED_APPSの設定
INSTALLED_APPS
は、Djangoインスタンスの中で有効化したいDjangoアプリケーションの名前を記載します。
pip install
などで、個別に追加するアプリケーションもここに追加していくことになります。
...
# 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
のままで進めましょう。
SQLite
は Python
に標準で組み込まれているため、接続するために何もインストールする必要がありません。
本番環境で使う場合には、AWS
やGCP
でも提供されているPostgreSQL
や MySQL
などのデータベースが良いでしょう。
公式のチュートリアルでは、PostgreSQL
を使用しています。
...
# 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
内にある、DATABASES
のdefault
項目内の以下のキーをデータベースの接続設定に合うように変更してください。
-
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
以外を使う場合、 データベースに接続するための、USER
や PASSWORD
そして HOST
などの追加設定を加える必要があります。
※詳細については DATABASES のリファレンスドキュメントを参照してください。
TIME_ZONE の設定
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
ファイルを以下のように編集してください。
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(リレーション)
class Question(models.Model):
...
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
...
ForeignKeyを使用して、リレーションを定義することができます。
これは、Choice
がQuestion
に関連付けられること意味します。
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.py
のINSTALLED_APPS
に追加する必要があります。
PollsConfig
クラスは、 polls/apps.py
にあるので、指定する記述は'polls.apps.PollsConfig'
となります。
下記のようにmysite/settings.py
を編集し、 INSTALLED_APPS
に上記のパスを追加します。
...
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
次のような結果が表示されます。
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;
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
) とモデルの小文字表記 のquestion
とchoice
を組み合わせて、polls_question
やpolls_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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38197/36301a76-6238-c8f4-1cb8-691642889ca0.png)](https://www.co.task.site?pr=qiita)