Modelとは?
Djangoでデータを表現する時に利用するクラス
Web アプリケーションのデータ構造を定義、操作するための抽象レイヤ
Modelとして定義することで、DB(テーブル)を簡単に作ることができる
説明を聞くだけだと退屈ですよね
一緒に考えて見ましょう
一度考えて作ってみた
code:サンプル
from django.db import models
class Author(models.Model):
pk = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, verbose_name='著者名')
class Book(models.Model):
pk = models.AutoField(primary_key=True)
author_id = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='著者')
title = models.CharField(max_length=255, verbose_name='名前(タイトル)')
release_date = models.DateField(verbose_name='発売日')
price = models.IntegerField(verbose_name='値段')
Modelにはフィールドオプションとフィールドの型が存在する
フィールドオプション
全て省略可能
上記だと例えば
primary_key
主キーを表す
verbose_name
人が読みやすい名前をつけるときに
フィールドの型
CharFieldは文字列を格納するフィールド
DateFieldは日付を格納するフィールド
ForeignKeyで外部キーをセットできる
このように記述することで、DB(テーブル)の作成時に、適切な型としてカラムを作成してくれる
では見てみよう
アプリケーションは
python manage.py startapp booksで作成できる
次のコマンドで良いはず
python manage.py makemigrations
python manage.py migrate
python manage.py makemigrationsを実行したら・・・
idを持つカラムについてエラーが起こっている・・・?
SystemCheckError: System check identified some issues:
ERRORS:
books.Author.pk: (fields.E003) 'pk' is a reserved word that cannot be used as a field name.
なるほど、こういうものが起こるのか
そしてリファレンスを見てみましょう
id フィールドは自動的に追加されますが、この処理を無効化することができます。自動インクリメントのプライマリーキーフィールド を参照ください。
なるほど、不要だった
python manage.py makemigrations を実行する
よし、できた
code:改良版
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=255, verbose_name='著者名')
class Book(models.Model):
author_id = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='著者')
title = models.CharField(max_length=255, verbose_name='名前(タイトル)')
release_date = models.DateField(verbose_name='発売日')
price = models.IntegerField(verbose_name='値段')
python manage.py makemigrationsを再実行
code: message
Migrations for 'books':
books/migrations/0001_initial.py
- Create model Author
- Create model Book
お、マイグレーションファイルが出来た
python manage.py migrate を実行する
できた!
・・・これで終わりじゃない
python manage.py dbshell
.table(s) でSQLiteならテーブルの一覧を閲覧できる
.schema <テーブル名> でテーブル定義を閲覧できる
出来上がったテーブル
books_author
books_book
.schema books_book で見てみよう
code: books_book
CREATE TABLE IF NOT EXISTS "books_book" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(255) NOT NULL,
"release_date" date NOT NULL,
"price" integer NOT NULL,
"author_id_id" bigint NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED
);
CREATE INDEX "books_book_author_id_id_78aac9b7" ON "books_book" ("author_id_id");
テーブル定義を見た結果
author_id_id カラム・・・!?
リファレンスを見てみましょう
Database Representation¶
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column. (You can change this explicitly by specifying db_column) However, your code should never have to deal with the database column name, unless you write custom SQL. You'll always deal with the field names of your model object.
DjangoはForeignKeyの場合、 _id という名前を裏側で付与してくれる
なんてこったい
そしてちなみに、テーブル名
サラッと流したけど、今回のテーブル名は
bools_author
books_book
だった
あれ、Model名だけではない?
App名_Model名 になっている?
リファレンスには・・・
myapp_person というテーブル名は、いくつかのモデルのメタデータから自動的に生成されますがそれを無効化することができます。詳細は Table names を参照ください。
ここで紹介されている Table namesはMeta option と呼ばれるものの1つ
Modelには内部クラスのMetaクラスというものが存在する
Meta optionについて
今回の場合、
db_table = "book"
db_table = "author"
としていたらテーブル名が book author になる
他にもDB(テーブル)に対して色々な設定がある
code: シン・改良版
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=255, verbose_name='著者名')
class Meta:
db_table = "author
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='著者')
title = models.CharField(max_length=255, verbose_name='名前(タイトル)')
release_date = models.DateField(verbose_name='発売日')
price = models.IntegerField(verbose_name='値段')
class Meta:
db_table = "book"
ちなみに最初の例では無理やり?主キーを作成しました