Django:models.py に記載した参考図書のコードについて疑問を調査した
Django:models.py に記載した参考図書のコードについて疑問を調査した
参考図書を元に色々書いていると疑問に思うことが多々出てきます。
今回はその中でもModelに関する事をまとめてみます。
『from django.db import models』って何?
app\models.py に記載するおまじない。まぁそりゃそうなんだろうけどね。
1 |
from django.db import models |
これはLaravel流で書けば【use django\db\models;】と同じ意味の様です。
いや、対象がディレクトリだから【namespace django\db\models;】の方が正しいかな。
つまりは「django\dbの中のmodelsディレクトリの中身を利用するよ」という宣言です。
「おまじない」ではなく、こう言う所の意味を知っておくことでプログラムが何してるか理解しやすくなりますよね。
Djangoのmodels.pyで書いたテーブル設定
参考図書を進めているとこんな記載がありました。
1 2 3 4 5 6 7 8 |
#models.py 内 class app(models.Model) user = models.ForeignKey(CustomUser, verbose_name='ユーザー', on_delete=models.PROTECT) title = models.CharField(verbose_name='タイトル', max_length=40) content = models.TextField(verbose_name='本文', blank=True, null=True) photo = models.ImageField(verbose_name='写真', blank=True, null=True) created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) |
うん、わからないことだらけ。と言う事で調べていきます。
ForeignKeyってなに?
ForeignKeyはテーブルのリレーションを示しています。
- 1対1のリレーション:models.ForeignKey(子, unique=True)
- 1対多のリレーション:models.ForeignKey(子)
- 多対多のリレーション:models.ManyToManyField(子)
Laravel のモデルで記載する【 belongsTo 】と同じ様です。
多対1のリレーションは?
LaravelだとModelsで『1対多』『多対1』の設定を施します。
なので、列挙された中に『多対1』が無い事が気持ち悪いのですが、Djangoでは意識する必要は無いようです。
Djangoでは『多対1』を意識しなくてよい
これはLaravelとDjangoのディレクトリ構造に起因するものの様です。
Laravelでは基本的に【 テーブルの数 = Modelの数】でSQLのテーブルそのものを表現した場所がModelになります。
命名規制でModelにテーブル名の単数形を付ける事からもこの構造が良くわかります。
一方で、Djangoでは【アプリの数 = Modelの数】となっています。
Models.pyの中には複数のテーブルを [ class テーブル名 ]として記載するため、あえて『 多対1 』を表現する必要が無いようです。※『1対多』が書いてあるだけで逆は理解できるので不要と言う事の様。
ちなみに、Laravelだとこんな感じでモデルに記載します。
1 2 3 4 5 6 7 8 9 |
# 『1対多』の時 ※親のモデルに記載 public function 子(){ return $this->hasMany('App\Models\子'); } # 『多対1』の時 ※このモデルに記載 public function 親(){ return $this->belongsTo('App\Models\親'); } |
Djangoって『多対1』は書かないのかぁ。
on_delete=models.PROTECTってなに?
これは、親レコードを削除した時にリレーションしている子側のレコードをどうするかを指示しています。
構文的にはこんな感じ。
1 |
models.ForeignKey (子, on_delete=models.指示) |
指示は基本的にSQLと同じと考えていいようです。レコード削除時の連動には以下のコードが使えます。
- CASCADE:リレーションしている値も一緒に消去する。
- PROTECT:リレーションしている値は削除しない(そのまま残す)。
- SET_NULL:リレーションしている値にNULLを代入する。※Nullableで許可してないとエラーが出る。
- SET(値):リレーションしている値に()で指示した値を入れる。
- SET_DEFAULT:リレーションしている値にデフォルト設定されている値を代入する。
- DO_NOTHING:リレーションしている値を空白にする。※リレーションに不具合をもたらす可能性が高いので要注意
verbose_nameってなに?
何となく意味は分かるんですけど、正確に知りたいなと。
管理画面でのモデルの名前を指定することができます。
なるほど。
これってValidationの時のエラーカラムを日本語で表記するように仕込めるって事かな?
まだテスト出来てないから不明だけど、Laravelはこの作業が苦痛なので出来たらありがたいなぁと。
あー、でも1件づつ設定するんだからLaravelと変わらないか。
verbose_name_pluralってなに?
参考図書にはこんな記載がありました。
1 2 |
class Meta: verbose_name_plural = 'app' |
verbose_nameがある上に何を指定するのか全く意味が推測できない。
これ「複数形表記を辞めて単数表記にしますね(つまりは『s』を取りますね)」と言う事らしいです。
【verbose_name=’ユーザー】と指定していても、レコードは複数あるので【ユーザーs】と表記されるのだとか。
それを verbose_name_plural に記載する事で【ユーザー】と言う表記に調整すると。
日本語ベースで考えれば面白い機能だけど…それほど重要性を感じなかったりする…。
SQLカラムのフィールド要素指定
記載しているとDjangoのModelはLaravelのdatabase\migrationsに近いものがあるなと感じてきました。
1 2 3 4 5 6 7 8 9 |
#Laravel マイグレーション記載例 Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->dateTime('last_login_at')->nullable(); $table->rememberToken(); $table->timestamps(); |
これと同じで、DjangoのModelではカラムの要素を指定していきます。
※LaravelのModelではValidationで使う要素指定はあるけど全カラムの指定はしない。
Djangoで使える要素指示は以下の通り。
Script | フィールド要素 | |
---|---|---|
文字列系 | CharField | 文字列 |
SlugField | スラッグ | |
URLField | URL | |
EmailField | メールアドレス | |
UUIDField | UUID | |
FilePathField | ファイルパス | |
GenericIPAddressField | IPアドレス(v4/v6/両方) | |
TextField | テキストエリア | |
数値系 | IntegerField | 整数+-10桁 |
IntegerField | 整数+-5桁 | |
SmallIntegerField | 整数+-5桁 | |
PositiveIntegerField | 10桁 マイナス値無し | |
PositiveSmallIntegerField | 5桁 マイナス値無し | |
BigIntegerField | 整数+-19桁 | |
FloatField | 浮動小数点 | |
DecimalField | 固定小数点 | |
理論値系 | BooleanField | チェックボックス |
NullBooleanField | セレクトボックス※NULL可能 | |
時間系 | DateTimeField | 日時 |
TimeField | 時間 | |
DateField | 日付 | |
DurationField | 期間 | |
ファイル系 | FileField | ファイル |
ImageField | 画像 |
Laravelにもファイル系ってあったのかな。
普通に何も気にせずcharでパス入れてたけど…。
まぁ、こんな感じでフィールドの指示を出せばそれに沿って動いてくれると言う事ですね。
まとめ
よく知っているLaavelと対比させていくことでDjangoも何となく理解出来てきました。
参考図書は一通り終わったので、次は思った姿を作ってみたいと思います。
その前に、まずはDockerでビルドしなきゃ。
-
前の記事
JavaScript:画面サイズが変わってもレコードを1行に収める方法 2020.11.17
-
次の記事
Laravel 使いが Django を触って混乱したパートについて その2 2020.11.19
コメントを残す