[Django] データベース(モデル)の設定
前回までにビューとURLディスパッチャの設定を行ったので今回はデータベース(モデル)の設定をしたいと思います。
シリーズ一覧
モデルって?
Djangoのモデルというのはデータベースを抽象化したものです。
モデルを利用する事で複雑なデータベースの設定(SQL文を書く)をする事なく、データベースを手軽に行うことができます。
Djangoではデータベースへのアクセスはこのモデルを通じて行います。
データベースの設計
今回はブログを作ろうと思っているのでブログに必要そうなテーブルとカラム、その型を列挙しようと思います。
- 記事
- タイトル (文字列)
- 本文 (文字列)
- 投稿日時 (時間)
- 最終更新日時 (時間)
こんなところですかね。
モデルを定義する
ではこれをDjangoのモデルにしてみましょう。
モデルの定義は各アプリケーションのmodels.pyに記述します。
今回の場合はmyblog/blog/models.py
に記述します。
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=128)
text = models.TextField()
posted_at = models.DateTimeField(auto_now_add=True)
last_modify = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
作りたいデータベースのテーブルごとにmodels.Model
クラスを継承したクラスを作成します。
上記のコードで言うところのArticle
です。
テーブル内のカラムはフィールドと呼び、クラス変数として定義します。
Articleクラスについて解説します。
まず、title = models.CharField(max_length=128)
のところが記事のタイトルに当たります。CharFieldField
は、少ない文字列のデータを保存します。max_length
で保存できる文字の最大数を設定する必要があります。
今回は128文字に制限しました。あまり長いタイトルをつけても仕方がないですしね。
次に、text = models.TextField()
のところが記事の本文にあたります。models.TextField
は多量の文字列を保存します。
特に何かを指定する必要はありません。
最後に、posted_at = models.DateTimeField(auto_now_add=True)
、last_modify = models.DateTimeField(auto_now=True)
がそれぞれ投稿日時、最終更新日時に当たります。DateTimeField
は時間を保存します。auto_now_add=True
を指定するとデータが登録されたときの日時を自動的に保存するようになります。auto_now=True
を指定するとデータが更新されたときの日時が自動的に保存されるようになります。
若干はズレれますが、
「CharField
とTextField
を分ける必要ないんじゃない?」
と思った方もいると思います。
では、なぜ分けるのか、端的に申しますとパフォーマンスの問題です。
TextField
はCharField
に比べるとデータベースのパフォーマンスが悪いのです。
具体的には、保存にかかるコスト、読み出しに関するコストが若干高いのです。
小規模なデータベースなら大した差にはならないのですが、これが大規模なものになるとかなりの差になります。
なのでもともと入力する文字数がわかっているなら、CharField
のほうが良いのです。
普段から少し気にしておくことで、いざというときに困らなくなるので気にするようにしましょう。
Djangoには、他にどんなフィールドがあるかはこちらにまとめてあるので興味のある人はどうぞ
因みにArticle
に定義している__str__
は文字列化したときにどんな文字列を返すかを指定するためのものです。
例えば、print()
で呼んだときなんかに使われます。
Articleオブジェクトをprintすると、記事のタイトルが表示されるようになります。
データベースの構築
さて、データベースの設計ができたのでいよいよデータベース構築していきます。
と言っても難しい事はなく二つのコマンドを実行するだけです。
manage.pyのあるディレクトリで
python manage.py makemigrations
python manage.py migrate
の二つを実行します。
一つ目のコマンドがDjangoにmodels.pyを更新したからチェックしてね。と言うコマンドで、
Migrations for 'blog':
blog\migrations\0001_initial.py
- Create model Article
こんな感じの出力があると思います。
二つ目のコマンドがデータベースファイルを実際に構築、更新するコマンドです。
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying blog.0001_initial... OK
Applying sessions.0001_initial... OK
こんな感じの出力になるはずです。
一つ目のコマンドをすっ飛ばすとDjangoがmodels.pyが更新されたことがわからないので、二つ目のコマンドを実行しても何も更新されません。
これらのコマンドを実行するとdb.sqlite3
というファイルができるはずです。
このファイルが実際にデータを保存してくれるデータベースファイルです。
主キー(primary key)
ちなみに今回の場合データベースのテーブルに主キーの設定を行いませんでした。
この場合、自動的にモデルへ内部的にid = AutoField(primary_key=True)
が追加されてテーブルの主キーが追加されます。
なので主キーの設定を行わなくても大丈夫です。
別途主キーを設定している場合、自動的にidが追加されることはありません。
まとめ
Djangoではデータベースのテーブルをモデル(クラス)で表現する。
カラムをフィールド(クラス変数)で表現する。
フィールドにはいろんな型があるので保存するテータの種類に合わせて適切なものを利用する。
モデルを更新したら
python manage.py makemigrations
python manage.py migrate
を実行する。
次回からは いよいよブログの機能を実装していきたいと思います。
views.pyとかurls.pyとかガシガシ改造しちゃうぞ!
なんちゃって…
次回