Django入門: モデルの作成 ~ 簡単な一行掲示板アプリを作る その8【Windows10】
- 作成日: 2020-10-20
- 更新日: 2023-12-26
- カテゴリ: Django
はじめに
この記事は「Djangoで一行掲示板を作る」というシリーズの記事です。
前回までにDjangoのプロジェクトとアプリを作成し、ビューからテンプレートを描画し、DBのマイグレーションを行い、動作テストを行いました。
今回から実際に掲示板のためのモデルを定義してマイグレーションを行っていきます。
前提としてOSはWindowsでコマンドプロンプトを使います。
仮想環境を使っているのでvenv\Scripts\activate
をアクティベートしています。
仮想環境については第一回の記事をご覧ください。
また初期位置として、プロジェクト内のmanage.py
のあるディレクトリに移動してある前提です。
モデルはいつ作るのか?
ところでモデルはいつ作るべきなのでしょうか?
基本的にはモデル作成の優先度は高いのが普通です。
つまり、プロジェクトの初期の段階でモデルを作るのがよくある方法です。
今回のシリーズではルート情報からビュー、そしてテンプレート、DBの初期マイグレーションという風に進んでいますが、別にこれはモデルの作成を一番最初にやってもかまいません。
このシリーズでは最初に「Hello, World!」を表示するためにこの手順で進んでますが、実際の開発では臨機応変に好きなところから開発を進めます。
また、開発を進めるとモデルが必要になる時がやってきますので、その時に作成するというのもありです。
掲示板のモデルの要件
今回作っているのは一行掲示板です。
ということは掲示板の利用者の投稿内容を表示できるようにする必要があります。
利用者の投稿内容はDBに保存する必要があるので、この「投稿内容」を表現するモデルが必要になることがわかります。
今回はこの「投稿内容」をPost
というモデルを作成して表現したいと思います。
Post
には投稿内容を表すcontent
というフィールドを作ります。
フィールドとは、モデル内に複数作れるデータを入れる箱のことですね。
Post
は変数と言うよりはデータのまとまりを表すものです。
そのまとまりの中にフィールドという実際のデータを入れる箱があるというイメージです。
モデル「Post」の作成
ではmanage.py
のあるディレクトリから作業を開始します。
モデルはアプリのディレクトリ以下のmodels.py
かmodels\
ディレクトリ以下に定義するのが一般的です。
あくまで一般的なので他の場所にモデルを定義することも可能です。
bbs\models.py
をエディタで開くと↓のような内容になっています。
from django.db import models
# Create your models here.
「Create your models here.」、つまり「あなたのモデルをここに作ってね」と書いてあります。
それからfrom django.db import models
はモデルを作成するのに必要なモジュールをインポートしています。
ではさっそくこのファイル内にモデルを作りましょう。
from django.db import models
class Post(models.Model):
"""
掲示板への投稿内容
"""
pass
↑のようにモデルはクラスとして定義します。
クラスはmodels.Model
を継承している必要があります。
クラスの名前は加工されてDB内のテーブルの名前になります。
たとえばアプリ名が「bbs
」であれば↑のモデルは「bbs_post
」という名前でテーブルが定義されます。
この名前は開発者が変更することも可能です。
さらにモデルPost
にフィールドを追加します。
from django.db import models
class Post(models.Model):
"""
掲示板への投稿内容
"""
content = models.CharField(max_length=140, help_text='掲示板の投稿内容')
モデル内のフィールドは↑のようにクラスの属性として定義します。
↓を詳しく見てみます。
content = models.CharField(max_length=140, help_text='掲示板の投稿内容')
Djangoにはモデルのフィールドを定義するためのクラスが多数用意されています。
models.CharField
というのはそのクラスの内の1つです。
このクラスは文字列を扱うためのフィールドです。
引数のmax_length
はこのフィールドに格納できる最大文字列数を指定します。↑の例では140
になっています。
help_text
は管理ページに表示するテキストで、サイト管理者にフィールドの役割を説明するための属性です。
これでモデルの定義は完了しました。
簡単ですね。
マイグレーションの実行
モデルを定義したら次はモデルのマイグレーションを行います。
今回作ったモデルは私たちのオリジナルのモデルなので、マイグレーションファイルはまだ作成されていません。
よって最初にmakemigrations
を実行してマイグレーションファイルを作成する必要があります。
manage.py
のあるディレクトリから↓のコマンドを実行すると↓のようなログが表示されます。
> python manage.py makemigrations
Migrations for 'bbs':
bbs\migrations\0001_initial.py
- Create model Post
↑のログを見ると「bbs\migrations\0001_initial.py
」というマイグレーションファイルが作成されているのがわかります。
このマイグレーションファイルをエディタで開いてみると↓のようになっています。
# Generated by Django 3.1.1 on 2020-09-21 20:06
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.CharField(help_text='掲示板のポスト内容', max_length=140)),
],
),
]
クラスMigration
がマイグレーションを実際に実行するスクリプトとなるクラスです。
operations
というリストがありますが、ここにDB
を操作するためのオペレーションが入ります。
↑の例ではmigrations.CreateModel
というのがそのオペレーションです。
このマイグレーションファイルですが、マイグレーションでエラーが起きた場合などに開発者が直接編集することがあります。
ではマイグレーションファイルを作成したのでマイグレーションを実行しましょう。
> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, bbs, contenttypes, sessions
Running migrations:
Applying bbs.0001_initial... OK
python manage.py migrate
でマイグレーションを実行すると↑のように「bbs.0001_initial... OK
」と表示されます。
先ほどのマイグレーションファイルの実行が成功したようです。
では試しにもう一回マイグレーションを実行してみてください。
> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, bbs, contenttypes, sessions
Running migrations:
No migrations to apply.
今度は↑のように表示されます。
「No migrations to apply.」、つまり「適用するマイグレーションはありません」と表示されます。
このようにDjangoでは実行したマイグレーションを記録して管理しています。
そのため一度実行したマイグレーションは再度実行されないようになっています。
この記録はDB内のdjango_migrations
というテーブルで管理されています。
DBの中身を見てみる
ここからは余談ですが、DBの中身を見てみたいと思います。
ただしこれは、環境にsqlite3
が入っている人限定の余談です。
環境でsqlite3
が使える場合はmanage.py
のあるディレクトリから↓のようにコマンドを実行すると、sqlite3
でdb.sqlite3
をオープンすることが出来ます。
> sqlite3 db.sqlite
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite>
sqlite3
のコマンドラインから↓のようにコマンドを実行すると、DB内のテーブルの一覧を表示できます。
sqlite> .tables
auth_group bbs_post
auth_group_permissions django_admin_log
auth_permission django_content_type
auth_user django_migrations
auth_user_groups django_session
auth_user_user_permissions
↑の内、bbs_post
というのが今回作成したモデルです。
django_migrations
のレコードを見てみます。
sqlite> select * from django_migrations;
1|contenttypes|0001_initial|2020-09-20 21:02:09.629999
2|auth|0001_initial|2020-09-20 21:02:09.712794
3|admin|0001_initial|2020-09-20 21:02:09.805690
4|admin|0002_logentry_remove_auto_add|2020-09-20 21:02:09.899446
5|admin|0003_logentry_add_action_flag_choices|2020-09-20 21:02:10.006855
6|contenttypes|0002_remove_content_type_name|2020-09-20 21:02:10.096771
7|auth|0002_alter_permission_name_max_length|2020-09-20 21:02:10.182166
8|auth|0003_alter_user_email_max_length|2020-09-20 21:02:10.281426
9|auth|0004_alter_user_username_opts|2020-09-20 21:02:10.382155
10|auth|0005_alter_user_last_login_null|2020-09-20 21:02:10.483390
11|auth|0006_require_contenttypes_0002|2020-09-20 21:02:10.566693
12|auth|0007_alter_validators_add_error_messages|2020-09-20 21:02:10.665567
13|auth|0008_alter_user_username_max_length|2020-09-20 21:02:10.757945
14|auth|0009_alter_user_last_name_max_length|2020-09-20 21:02:10.848351
15|auth|0010_alter_group_name_max_length|2020-09-20 21:02:10.964376
16|auth|0011_update_proxy_permissions|2020-09-20 21:02:11.054930
17|auth|0012_alter_user_first_name_max_length|2020-09-20 21:02:11.140816
18|sessions|0001_initial|2020-09-20 21:02:11.227002
19|bbs|0001_initial|2020-09-21 20:12:04.857470
↑の↓の行を見るとわかりますが、しっかりと今回のマイグレーションが記録されています。
19|bbs|0001_initial|2020-09-21 20:12:04.857470
次にbbs_post
のテーブルの定義を見てみます。
sqlite> .schema bbs_post
CREATE TABLE "bbs_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "content" varchar(140) NOT NULL);
↑を見ると、id
とcontent
が定義されているのがわかります。
id
ですが、Djangoのモデルは自動でid
というフィールドをテーブルに定義します。このフィールドはテーブルのプライマリーキーとして利用されます。
おわりに
今回は掲示板用のモデルを作成しました。
次回から今回作ったモデルを使ったコードを書いていきたいと思います。
🦊 < 来週へ続く