[Django] データベース(モデル)の設定

前回までにビューとURLディスパッチャの設定を行ったので今回はデータベース(モデル)の設定をしたいと思います。

シリーズ一覧

  1. プロジェクトの作成とアプリケーションの作成 <- 今回
  2. view関数の書き方
  3. URLの指定の仕方(URLディスパッチャ)
  4. データベース(モデル)の設定 <- 今回
  5. 記事の投稿ページの作成
  6. 記事の一覧ページと詳細ページの追加
  7. 記事の編集ページと記事の削除機能の追加
  8. いいね機能の追加
  9. コメント機能の追加
  10. Bootstrapを利用したwebデザイン

モデルって?

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を指定するとデータが更新されたときの日時が自動的に保存されるようになります。

若干はズレれますが、
CharFieldTextFieldを分ける必要ないんじゃない?」
と思った方もいると思います。

では、なぜ分けるのか、端的に申しますとパフォーマンスの問題です。
TextFieldCharFieldに比べるとデータベースのパフォーマンスが悪いのです。
具体的には、保存にかかるコスト、読み出しに関するコストが若干高いのです。
小規模なデータベースなら大した差にはならないのですが、これが大規模なものになるとかなりの差になります。
なのでもともと入力する文字数がわかっているなら、CharFieldのほうが良いのです。
普段から少し気にしておくことで、いざというときに困らなくなるので気にするようにしましょう。

Djangoには、他にどんなフィールドがあるかはこちらにまとめてあるので興味のある人はどうぞ

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とかガシガシ改造しちゃうぞ! なんちゃって…

次回

[Django] 記事の投稿ページの作成