Django – モデル・テーブル等の名前

目的

Djangoでアプリケーションとモデルを作成し、マイグレーションした場合の、テーブル名、フィールド名などを確認。アプリケーション名をmy_app、モデルクラス名をMyModel1MyModel2とする。

なお、自動付与されるテーブル名は変更することが可能

手順

アプリケーション作成

アプリケーション名はスネークケース(my_app)

アプリケーション構成クラス名の確認

アプリケーション名がスネークケースの場合、アプリケーション構成クラス名はアッパーキャメルケースになり、Configが付加される。

my_app → MyAppConfig

アプリケーション登録

settings.pyINSTALL_APPSにアプリケーション構成クラスを追加。ここではアプリケーション構成クラスを追加している。

モデル定義

my_apps/models.pyファイルで2つのモデルクラスMyModel1MyModel2を定義。MyModel2にはMyModel1への参照キーを設定する。

マイグレーションファイル作成

マイグレーション

マイグレーションを実行してテーブルを生成させる。

テーブル確認

テーブル名は’アプリケーション名_小文字化されたモデル名‘となる。キャメルケースのモデル名をスネークケースにはしてくれない。

my_app + MyModel1 → my_app_mymodel1
my_app + MyModel2 → my_app_mymodel2

テーブル構造を確認。

MyModel2の外部キーは、’参照先モデル名(スネークケース)_id‘となる。この場合は参照先がMyModel1なので、

MyModel1 → my_model1_id

まとめ

これを表で整理すると以下のようになる。

my_app
アプリケーション構成クラス名(生成) MyAppConfig
モデルクラス名(定義) MyModel1 MyModel2
テーブル名(マイグレーション) my_app_mymodel1 my_app_mymodel2
外部キー名(マイグレーション) my_model1_id

これを何とか図にすると、以下のようになる。

まとめると以下のようになる。

  • アプリケーション名:スネークケース
    →アプリケーション構成クラス名:アッパーキャメルケース
  • モデルクラス名:アッパーキャメルケース
  • テーブル名:アプリケーション名_小文字化されたアプリケーション構成クラス名
  • 外部キー名:参照先のモデル名(スネークケース)_id

 

Django – settings.py – INSTALLED_APPS

 

概要

settings.pyINSTALLED_APPS配列でアプリケーションを登録する。

Django – settings.pyへ。

デフォルトの内容

プロジェクト作成直後のsettings.pyにおけるINSTALLED_APPSの内容は以下の通り。コメントはこちらで追記。

アプリケーションの登録

アプリケーション登録のためには、アプリケーション構成クラスを登録するが、書き方には2通りある。登録するアプリケーションをmy_appとすると、以下の通り。

  1. 'my_app.apps.MyAppConfig',
  2. 'my_app',

1の書き方は、明示的にアプリケーション構成クラスを書く方法。

manage.pyでアプリケーションを作成するとmy_appディレクトリ下にapps.pyファイルが作成され、アプリケーション構成クラスが定義される。

アプリケーション構成クラス(MyAppConfig)はAppConfigを継承している。またアプリケーション名のスネークケースがクラス名ではアッパーキャメルケースになり、Configが付加されている(モデル・テーブル等の名前を参照)。

2の書き方は、アプリケーションパッケージ名を書く方法。

この場合Djangoはmy_appパッケージのmy_app/__init__.py内のdefault_app_config変数で設定されたアプリケーション構成クラスを使う。

  • デフォルト状態で__init__.pyが空の場合、AppConfigクラスが使われる
  • __init__.pydefault_app_config='my_app.apps.MyAppConfig'が設定されていれば、apps.py内のMyAppConfigが使われる

参考サイト:Django アプリケーションの登録

 

Django – migration – 初期状態

概要

プロジェクト作成直後のマイグレーションを記録。

初期状態

プロジェクト作成直後のマイグレーションの状態は以下のとおりで、INSTALLED_APPSで設定されたアプリケーションに対応したマイグレーションファイルが準備されている。

マイグレーション実行

初期状態でマイグレーションを実行。

作成されるテーブル

マイグレーションの状態

初期状態で確認したマイグレーションが実行されている。

 

Django Tutorial – モデルの作成とマイグレーション

概要

Djangoのモデル作成について、チュートリアルに沿って進めた内容の整理。mysiteプロジェクトのpollアプリケーションのモデルを作成する手順。

前提

  • mysiteプロジェクト作成・初期設定済み
  • pollsアプリケーション作成済み

手順

  • models.pyを編集し、モデルクラスを記述
    • models.pyはアプリケーションディレクトリー下
    • モデルクラスの内容=テーブルのフィールド構成
  • settings.pyINSTALLED_APPSにアプリケーション登録
    • アプリケーション構成クラスを追加
  • manage.py makemigrationsコマンドでマイグレーションファイルの準備
    • 必要ならmanage.py sqlmigrateでSQLを確認
  • マイグレーション実行

models.pyの編集

モデルはデータベースの操作をラップし、DBMSによる差異を吸収する。

  • Djangoでは、モデルはアプリケーションごとに作成する
  • モデルの構造はPythonのクラスとして記述する
  • モデルの記述場所はアプリケーションディレクトリー下のmodels.py

以下のツリーでmodels.pyの場所を確認しておく。

アプリケーション作成直後のmodels.pyファイルの内容は以下のとおり。モデルが継承するmodelsパッケージをインポートしている。

QustionモデルとChoiceモデルを作成するため、models.pyを以下のように編集。

要点は以下のとおり。

  • モデル名は単数形でQustionChoiceの2つ
  • 各モデルはdjango.db.models.Modelクラスを継承
  • 各モデルクラスのフィールドはmodelsパッケージのField関係クラスのインスタンス
    • たとえばCharFieldは文字列フィールド、DateTimeFielddatetime型のフィールドなど
  • こちらで定義したquestion_textpub_dateなどのフィールド名はPythonのコードで扱われるとともに、データベースのフィールド名としても使われる
  • Fieldコンストラクターの第1引数では、より人が読みやすいフィールド名を付けることができる
    • 上の例では'date published'
  • Fieldによっては必須の引数があり、たとえばCharFieldmax_lengthは必須であり、データベースフィールド定義のほか、バリデーションにも使われる
  • ForeignKeyは外部キーであり、Choiceモデルのquestionフィールドは1つのQuestionモデルを参照する
    • また参照元の削除に伴って削除される設定もされている

なお、自動作成されるテーブル名を変更したい場合はここを参照

アプリケーションの追加

pollsアプリケーションを作成してモデルを定義したが、これらはまだDjangoのプロジェクトには認識されていない。プロジェクトとしてモデルとデータベースを結びつけるマイグレーションのためには、アプリケーションをプロジェクトに登録する必要がある。

アプリケーション登録のために、settings.pyINSTALLED_APPSに記述を加える。ここではアプリケーション構成クラスを追加する。

ここではpollsアプリケーションのPollsConfigクラスを登録している。このクラスはアプリケーション作成時にDjangoにより生成、アプリケーションのapps.pyファイルで定義されていて、AppConfigクラスを継承している。

pollsアプリケーションの場合はpolls.apps.PollsConfigとして参照される。

マイグレーションファイル作成

マイグレーションファイルの作成は以下のコマンドで実行。

以下はpollsアプリケーションの実行結果で、アプリケーションのmigrationsディレクトリーにマイグレーションファイル(0001_initial.py)が作成され、マイグレーションによりQuestionChoiceの2つのモデルが作成されることが表示されている。

0001_initial.pyファイルの内容を見てみる。

2つのモデルとも、クラス定義にはなかったidフィールドが追加されている。これらのフィールドはAUTO_INCREMENTタイプで自動的に作成され、主キー(primary_key)として設定されている。

SQLの確認

マイグレーションファイルの内容でデータベースのテーブルを作成する際のSQLも確認することができる。

以下はpollsアプリケーションのマイグレーションファイルをSQLで確認した結果。

読み易いように整形した結果。

MySQLの場合、

  • 自動的に作成されたidAUTO_INCREMENTPRIMARY KEYが設定されている
  • CharField(max_length=200)varchar(200)となっている
  • datetime(6)の引数6は秒未満の小数部の桁数
  • モデルクラスではChoice.questionQuestionを参照するよう定義したが、SQLではpolls_choiceテーブルのquestion_idpolls_questionテーブルのidを参照するという風に、IDを介して参照している

マイグレーション実行

生成されたマイグレーションファイルに基づいて、以下のコマンドでマイグレーションを実行。

以下は今回の例で実行した結果。

manage.py showmigrationsで、pollsアプリケーションのマイグレーションファイルが実行されているのが確認できる。

MySQL側でテーブルを確認。2つのテーブルpolls_questionpolls_choiceが作成されている。

2つのテーブルの定義を確認。

 

Django – マイグレーション操作

 

マイグレーションファイル作成

アプリケーションを作成・登録して、model.pyにモデルクラスを記述した後に実行。再実行の際は一度マイグレーションファイルを消した方がよい模様。

状態確認

マイグレーションの状態

マイグレーション実行のSQL表示

マイグレーション

未実行のマイグレーションを実行。

指定したアプリケーションとマイグレーションが既にマイグレーション済みの場合はロールバックになる点に注意。

ロールバック

指定したマイグレーションの手前まで

0001_initialも含めて全て

マイグレーションファイル削除

migrationsディレクトリー下のマイグレーションファイルとキャッシュを削除。

 

Django – settings.py – TEMPLATES

概要

settings.pyTEMPLATESは配列・辞書の入れ子になっている。

'DIRS'
プロジェクトルート直下のテンプレートディレクトリーを指定する。そのサブディレクトリーも探索される。
'APP_DIRS'
アプリケーションディレクトリー下のテンプレートディレクトリー探索を有効にする。そのサブディレクトリーも探索される。

Django – settings.pyへ。

テンプレートの探索場所の詳細についてはこちら

初期状態

settings.py生成直後のTEMPLATESの内容は以下のとおり。

 

'DIRS': []と設定されていて、プロジェクトルート(この場合はprojectroot/)直下は探索されない。

'APP_DIRS': Trueと設定されていて、各アプリケーションディレクトリー下のtemplatesディレクトリーが探索される。

DIRS

プロジェクトルート直下のテンプレートディレクトリーを指定する。たとえば以下のようにtemplatesディレクトリーを準備した場合。

準備したtemplatesを探索させるためには、以下のように設定する。

あるいは以下のようにベースディレクトリーからのパスであることを明示する。この場合settings.pyimport osが必要。

ディレクトリーの指定はサブディレクトリーでもよい。たとえばconfigディレクトリー下のtemplatesディレクトリーとしたければ以下のように記述。

APP_DIRS

APP_DIR=Trueとすると、各アプリケーションディレクトリー下のtemplatesディレクトリーが探索される。そのサブディレクトリーも探索される。

 

 

Django – settings.py

Djangoの設定ディレクトリー下に生成されるsettings.pyの内容を整理する。個別に設定想定していなければ、ここでは以下の構成を仮定している。

 

INSTALLED_APPS

TEMPLATES

DATABASES

国際化

 

Django – settings.py – 国際化

概要

settings.pyLANGUAGECODE変数で言語コードを、TIME_ZONE変数でタイムゾーンを指定する。

Django – settings.pyへ。

初期状態

settings.py生成直後の国際化関係の内容は以下のとおり。

日本語の場合の設定

言語コード

日本語に設定。

タイムゾーン

タイムゾーンを指定、有効化(初期状態のTrueのまま)。

Djangoは全ての日付=datetimeオブジェクトをUTCでデータベースに保存する。タイムゾーンの表現を任意に変更可能。

 

Django – settings.py – DATABASES

概要

Djangoでのデータベース設定は、settings.pyDATABASES辞書で設定する。

Django – settings.pyへ。

初期状態

settings.py生成直後のDATABASESの内容は以下のとおり。デフォルトでSQLiteが指定されている。

MySQLの場合の設定

MySQLを使う場合は以下のように記述。

ただし事前にmysqlクライアントのインストールが必要。

 

Django – ルーティング – urls.py

概要

リクエストされたURLから、Django内部で必要なview関数を呼ぶためのルーティングは、urls.pyで設定する。

  • urls.pyはプロジェクト設定ディレクトリーの下か、各アプリケーションディレクトリーの下
  • アプリケーションディレクトリー下のurls.pyは新規に作成し、設定ディレクトリーのurls.pyincludeする
  • ルーティングはurls.pyurlpatterns配列にpath関数で登録する
  • path関数の引数に、URLパターンとビュー関数を与える

ルーティングの流れについてはこちらも参照

設定ディレクトリー下のurls.py

プロジェクト構成

djangobasicsプロジェクトを作成。設定ディレクトリーをconfとし、アプリケーションurlincludeを作成・登録した場合のツリーは以下の通り。

ビューとテンプレート

urlinclude/views.pyを以下のように編集する。

urlinclude/templates/urlincludeディレクトリーを作成し、その下にindex.htmlを以下の内容で作成。

pathの登録

設定ディレクトリーconfの下のurls.pyに以下のように追記。以下、このurls.pyを「グローバルなurls.py」と呼ぶ。

まずアプリケーションのviewsモジュールをインポートしている。

そしてホスト名/アプリケーション名でindexビュー関数が呼ばれるようルーティング。

ここでhttp://localhost:8000/urlincludeでブラウザーからアクセスすると、index.htmlの内容が表示される。

アプリケーション下のurls.py

グローバルなurls.pyの問題点

設定ファイル直下のurls.pyでのpath登録は、

  • デフォルトで作成されたurls.pyを編集すればよい
  • 任意のアプリケーションのルーティング登録ができる

ただし以下のような問題点がある。

  • 登録するビューのアプリケーションをインポートする必要がある
  • 全てのビューを登録するため見通しが悪くなる
  • アプリケーション間でビューの名前の衝突が起こり得る

このため一般にはアプリケーションごとにurls.pyを作成し、そのモジュールを設定ディレクトリー下のグローバルなurls.pyincludeする。

ビューとテンプレート

ビューとテンプレートは先の例と同じものを使う。

アプリケーションのurls.pyの準備

アプリケーションディレクトリー下に、以下の内容でurls.pyファイルを作成する。conf/urls.pyのように自動作成されないので、新たに作成する必要がある。

ツリーは以下の通り。

グローバルなurls.pyの編集

conf/urls.pyを以下のように編集する。

  • django.urlsパッケージのpathモジュールに加えて、includeモジュールもインポートする
  • urlpatterns配列にpath関数を追加し、アプリケーションのurls.pyincludeする

ここでhttp://localhost:8000/urlinclude/indexにアクセスすると、index.htmlがブラウザーに表示される。

留意点

グローバルなurls.pyでは、個々のアプリケーションのviewsモジュールをインポートする必要はない。

include関数の第1引数はアプリケーション名を使ったディレクトリーで、その後にアプリケーション内で定義したパスが続く。

  • 今回の例では'urlinclude/' + 'index''urlinclude/index'
  • 末尾に'/'がないとエラーになる

include関数の引数は、'アプリケーション.urls'の文字列。

  • 文字列にしていないと”名前が見つからない”、とエラーになる

直接テンプレートを表示する

path関数で直接テンプレートを表示させることもできるが、少し手間が必要。

  • urls.pyTemplateVierwクラスをインポート
  • path関数の第2引数にTemplateView.as_view()メソッドを与えてテンプレートを指定

たとえば以下は、index.htmlと同じディレクトリーにexample.htmlを作成し、これを直接path関数から呼び出す例。