サンプルモデル(PostgreSQL)
● テーブル1
【カテゴリTBL category】
カテゴリID cid integer primary key NOT NULL
カテゴリ名 cname varchar(20) NOT NULL unique
取り消し del_flg varchar(1) default '0'
create table category (cid integer primary key NOT NULL, cname varchar(20) NOT NULL unique, del_flg varchar(1) default '0');
insert into category (cid, cname, del_flg) VALUES (1, '菓子', DEFAULT);
insert into category (cid, cname, del_flg) VALUES (2, '飲料', DEFAULT);
insert into category (cid, cname, del_flg) VALUES (3, '弁当', DEFAULT);
● テーブル2
【商品TBL product】
連番 id serial primary key
商品CD pcd integer NOT NULL unique
商品名 pname varchar(20) NOT NULL
カテゴリ category_id integer NOT NULL
取り消し del_flg varchar(1) default '0'
create table product (id serial primary key, pcd integer NOT NULL unique, pname varchar(20) NOT NULL, category_id integer NOT NULL, del_flg varchar(1) default '0');
ALTER TABLE product ADD CONSTRAINT category_id FOREIGN KEY (category_id) REFERENCES category (cid);
insert into product (pcd, pname, category_id) values (1, 'チョコボール', 1);
insert into product (pcd, pname, category_id) values (2, 'キノコの山', 1);
insert into product (pcd, pname, category_id) values (3, 'エビアン', 2);
insert into product (pcd, pname, category_id) values (4, '麦茶', 2);
insert into product (pcd, pname, category_id) values (5, '生姜焼き弁当', 3);
insert into product (pcd, pname, category_id) values (6, '幕の内弁当', 3);
● テーブル3
【カテゴリ詳細TBL category_detail】
連番 id serial primary key
カテゴリid category_id integer NOT NULL unique
詳細 detail_name varchar(100) NOT NULL
取り消し del_flg varchar(1) default '0'
create table category_detail (id serial primary key, category_id integer NOT NULL unique, detail_name varchar(100) NOT NULL, del_flg varchar(1) default '0');
insert into category_detail (category_id, detail_name) values (1, 'チョコ・スナック・煎餅');
insert into category_detail (category_id, detail_name) values (2, '水・炭酸・コーヒー');
insert into category_detail (category_id, detail_name) values (3, 'セブン・ローソン・オリジン');
ちょっとカスタマイズ
Django は、モデルをアプリ単位で管理しています。
そのため、モデル定義があちこちに散在する結果となり非常に視認性が低下します。
そこでモデル単位でファイルを作成し、1つのディレクトリで管理すると非常に見た目も綺麗になります。
● 管理するアプリ
モデルを管理するアプリは users が一般的です。
このアプリに models ディレクトリを作成し __init__.py を作成します。
※models.py は Django の制約上空でも必要らしい。。
次に hoge テーブルの定義クラス Hoge(今まで models.py にあったと仮定) をファイル hoge.py を作成しクラス毎移動します。
[users]
+---[models]
+---[__init__.py]
+---[hoge.py]
次に __init__.py にモデルが追加された事を知らせるため以下を記述します。
from users.models.hoge import Hoge
更に、hoge.py に移動したクラス Hoge も一部追記します。
これは、本来モデルが定義されたディレクトリがアプリ名と Django が認識するため、
モデル定義の Meta クラスで app_label を定義してアプリ名を教える必要があるためです。
class Hoge():
class Meta:
app_label = 'users'
以上でモデルが models ディレクトリにまとまります。
モデルの定義(models.py)
● 定義するクラスの制約は以下となります
テーブル名 クラス名
カラム名 クラス変数名
データ型 クラス変数に代入するオブジェクト(Fieldクラスのインスタンス)
その他 Fieldクラスのオプション
● 暗黙の制約は以下となります
Fieldクラスのオプションに何も指定しなければ、NOT NULL制約がかかります
PRIMARY KEYとなるクラス変数を定義しない場合、idが自動的に定義されます
● テーブル名の命名規則
[アプリ名]_[クラス名]となります
例えば util アプリに category テーブルを定義すると、テーブル名は util_category となります。
任意のテーブル名にするには、Meta クラスを定義し、db_table 変数で定義します。
● モデルの定義を変更したら
以下をプロンプトから叩く(DJANGO と DB の整合性を担保する)
python manage.py makemigrations
python manage.py migrate
※もしエラーになったら、各アプリの migrations の __init__.py 以外の .py ファイルを削除してみる
【テーブル1】の定義
from django.db import models
#モデル名
class Category(models.Model):
class Meta:
#テーブル名が【アプリ名_category 】とならない様に定義している
db_table = 'category'
verbose_name = 'モデルのラベル名'
verbose_name_plural = 'モデルのラベル名(複数形)'
cid = models.IntegerField(primary_key = True)
cname = models.CharField(max_length = 20, unique = True)
del_flg = models.CharField(max_length = 1, default = '0')
def __str__(self):
#オブジェクト自身を参照した際の返却する文字列を設定する
return self.cname
【メモ】
Django の主キーは単純な1からの連番です。
これを複雑な重複しないキーにするライブラリ「uuid」があります。
例)
import uuid as
uuid_lib
uuid = models.UUIDField(default=
uuid_lib.uuid4,primary_key=True, editable=False)
※注意として、uuid を DjangoAPI を利用してモデルから取得しようとすると「-」が紛れ込んだ文字列が返却されます。
本来はハイフンがない文字列なので、テンプレート等で表示する場合は{{row.uuid|cut:'-'}}でハイフンを削除した方が良いです。
【注意】
Django のフィールド型には Char 型がありません。
その場合は、独自で定義したクラスを作成し、そのフィールドを使用する様にします。
例)
""" カスタマイズフィールド char型を定義 """
#CharField を継承する
class MyCharField(models.CharField):
def __init__(self, *args, **kwargs):
#引数に max_length=* を指定するとchar(*) と返却される
self.__length = kwargs['max_length']
super().__init__(*args, **kwargs)
def db_type(self, connection):
#ここでオーバーライドし、char 型を返却する
return 'char(' + str(self.__length) + ')'
● META オプション
上記でも軽くふれた様に、例えばテーブル名を指定するオプションに db_table があります。
以下は、その他のオプションを説明します。
| abstract = True |
このモデルは抽象基本クラスになります。 |
| app_label = 'hoge' |
モデルがINSTALLED_APPSアプリケーション外で定義されている場合は、それが属するアプリケーションを宣言する必要があります。 |
| db_table = 'hoge' |
モデルに使用するデータベーステーブルの名前 |
| db_tablespace |
このモデルに使用するデータベース表領域の名前 |
| managed = False |
False場合、このモデルに対してデータベース表の作成または削除操作は実行されません。(ビューテーブルで有効)
※モデルを定義する場合、ビューテーブルでも主キーの定義は必要です
|
モデルの制御(登録、更新、削除)
主に[views.py]で記述する感じ。
まずは使用したいモデルをインポートする
例)
from アプリ名.models import
Category ※
Category は、テーブルクラス名
● 登録
例)
c = Category(cid = 4, cname = 'ほげ') ※主キーが自動裁判の場合は、主キーの定義はしないで良い
c.save()
● 更新
例)
c = Category(cid = 4, cname = 'パン') ※主キーが存在する場合は更新となる
c.save()
● 削除
例)
c = Category(cid = 4)
c.delete() ※主キーが存在するインスタンスなら削除できる
【メモ】
save する場合は、フォームデータの保存が多いと思うが、単純に
form.save() で失敗する場合(
form = フォームインスタンス)がある。
例えばフォームにはなかったが、モデルのカラムとしては not null 属性で定義がある場合や、外部キーを定義していて変数名が _id 抜きの変数名になっている場合は失敗する。
これを回避するには、一旦仮の保存用のモデルインスタンスを作成し、プロパティを修正する方法があります。
例)
instance =
form.save(commit = False)
上記の引数を付与する事で一旦保存用のインスタンスを作成できます。
このインスタンスに足りないカラム等を調整し、
instance.save() とする事で保存します。
例)
instance.m_pref_id = request.POST['m_pref_id'] ※必要なカラム名に値を代入等する。
また、更新処理の場合は全てのカラムを更新する仕様となっています。
save() の名前付き引数に update_fields = ['カラム名','カラム名'...] とする事で更新するカラムを制限する事は可能です。(主キーを設定するとエラーとなるので注意!)
上記引数には、【このカラム名以外は更新】と言った引数はないので100個のカラム中2つのカラム以外を更新したい場合は98個のカラム名を引数にする必要があります。
これをお手軽にする方法は以下の様にすれば良いかも。
例)
uf = []
for f in Hoge._meta.get_fields():
#カラム属性が主キーではなく、かつカラム名が insert_date でない場合
if f.primary_key != True and f.name != 'insert_date':
#更新したいカラム名をリストに追加する
uf.append(f.name)
instance.save(update_fields =
uf)
モデルの制御(検索)
まずは使用したいモデルをインポートする
例)
from アプリ名.models import
Category ※
Category は、テーブルクラス名
● 単純な検索
例)
#全件検索
res =
Category.
objects.
all()
for row in res:
#ループで個々の値を参照できる
print(row.cname)
#全件取得 + 特定のカラムのみ取得
res =
Category.
objects.
values('cid','cname')
for row in res:
#これは辞書型で取得できる
print(row)
#1件のみ取得
res =
Category.
objects.
get(cid = 2)
print(res.cname)
【注意】
get メソッドは、取得件数が1件以外の場合はエラーとなります
【テクニック】
フィールド名を動的に設定したい場合は、以下の様にする
name = 'cid'
id = 2
kw = {name:id}
res = Category.objects.get(**kw)
● OR 検索
OR句を使用する場合は Q をインポートする
例)
from django.db.models import Q
~ 省略 ~
res = Category.objects.all().filter(Q(cid=1)|Q(cname='飲料'))
for row in res:
print(row.cname)
● filter / exclude
SQL の WHERE 句となる
例)
#id__in=[1,2] は、SQL の id in (1,2) の意味
res =
Category.
objects.
all().filter(cid__in=[1,2])
for row in res:
#オブジェクトで取得する
print(row.cname)
#引数を増やせば AND 検索となる
res =
Category.
objects.
all().filter(cid__in=[1,2], cname='飲料')
#not の意味となる
res =
Category.
objects.
all().exclude(cid__in=[1,2])
【以下演算子の種類】
| 挙動 |
SQL上での演算子 |
Django |
例 |
| 完全一致 |
= |
a |
a = ... |
| 完全一致 |
= |
exact |
a__exact=... |
| 大文字小文字区別無しの一致 |
iLIKE '...' |
iexact |
a__iexact=... |
| 大文字小文字区別有りの部分一致 |
like '%...%' |
contains |
a__contains=... |
| 大文字小文字区別無しの部分一致 |
ilike '%...%' |
icontains |
a__icontains=... |
| 大文字小文字区別有りの前方一致 |
like '...%' |
startswith |
a__startswith=... |
| 大文字小文字区別無しの前方一致 |
ilike '...%' |
istartswith |
a__istartswith=... |
| 大文字小文字区別有りの後方一致 |
like '%...' |
endswith |
a__endswith=... |
| 大文字小文字区別無しの後方一致 |
ilike '%...' |
iendswith |
a__iendswith=... |
| ...より大きい |
> |
gt |
a__gt=... |
| ...以上 |
>= |
gte |
a__gte=... |
| ...より小さい |
< |
lt |
a__lt=... |
| ...以下 |
<= |
lte |
a__lte=... |
| リストに含まれている物を抽出 |
in (...) |
in |
a__in=['...', '...'] |
| 日付や日時に対する範囲指定 |
between |
range |
a__range=(start_date, end_date) |
| 年の厳密一致 |
between 'xxxx-01-01 00:00:00'
and 'xxxx-12-31 23:59:59'
|
year |
a_year=xxxx |
| 月の厳密一致 |
(exact ('month' from ...) = ...) |
month |
a__month = ... |
| 日の厳密一致 |
(exact ('day' from ...) = ...) |
day |
a__day = ... |
| NULL を取り出す |
is null |
isnull |
a__isnull=True |
| NULLでないのを取り出す |
is not null |
isnull |
a__isnull=False |
● order_by
SQL の ORDER BY 句となります
例)
res = Category.objects.all().order_by('cid') ※昇順
res = Category.objects.all().order_by('-cid') ※降順
● limit / offset
例)
res = Category.objects.all()[:2] ※limit のみ
res = Category.objects.all()[1:2] ※offset 付き
● distinct
例)
res = Category.objects.values('hoge').distinct()
平文のクエリを発行する
平文を発行するには、
connection.cursor メソッドを使います。
例)
from django.db import connection
~ 省略 ~
sql = "select cid,cname from category"
cursor =
connection.cursor()
#SQL 実行
cursor.execute(sql)
res =
cursor.fetchall()
for row in res:
#タプル型で値を取得できる (2, '飲料')
print(row)
sql = "select cid,cname from category where cid in %s and cname=%s"
#パラメータを渡す事もできます
cursor.execute(sql,[(1,2),'飲料'])
【メモ】
結果セットがタプル型だと何かと扱いにくい。
そんな場合は辞書型に変換すると便利です
例)
sql = "select cid,cname from category"
cursor = connection.cursor()
cursor.execute(sql)
desc = cursor.description
res = [dict(zip([col[0] for col in desc], r)) for r in cursor.fetchall()]
for row in res:
print(row) ※辞書型で取得できる {'cid': 2, 'cname': '飲料'}
トランザクション
from django.db import transaction
~ 省略 ~
#自動コミットを解除
transaction.set_autocommit(False)
~ 適当な SQL 発行 ~
#コミットする
transaction.commit()
#ロールバックする
transaction.rollback()
外部キー
【テーブル1:category】に対して【テーブル2:product】は、外部キーを持っています
product.category_id は、category.cid の外部キー
この関係のとき、テーブル product を検索すると category 情報も同時に抽出する様にするには、
モデル Product を以下の様に定義する
例)
class Product(models.Model):
class Meta:
db_table = 'product'
pcd = models.IntegerField(unique = True)
pname = models.CharField(max_length = 20)
category = models.ForeignKey(Category,to_field='cid', on_delete=models.PROTECT)
del_flg = models.CharField(max_length = 1, default = '0')
【メモ】
引数 verbose_name は、参照先テーブルの論理名(日本語名)を記述する
引数 to_field は、参照先テーブルのカラム名を指定する(デフォルトでは、リレーション先のオブジェクトの主キー)
引数 on_delete は、外部キーの参照元のテーブルが削除されそうになった場合の【許可】【拒否】を指定するものです
models.PROTECT 【拒否】
models.CASCADE 【許可】 ※親のデータはもちろん、親に紐つく子のデータ全てが削除される
【注意】
変数 category のカラム名は category_id です。
外部キーは勝手に【変数名】+【_id】となります!
検索例)
res = Product.objects.all()
for row in res:
print(row.category.cname) ※category の情報を取得できる
【逆参照】
models.ForeignKey を定義したモデル Product からは、外部キーを利用して category の情報を上記の様に取得できます。
当然 category からも Product の情報を取得でき、これを【逆参照】といいます。
逆参照をするには、モデル Product の models.ForeignKey に以下のパラメータを追加します。
related_name = '
product_set' ※
product_set は、任意の名前
この状態で以下の様に取得できます。
例)
#【1 対 多】の関係なので、まずは category を1レコードに絞る
res = Category.objects.get(cid=2)
#その結果オブジェクトに対し、定義した product_set を all メソッドで実行する
res = res.product_set.all()
for row in res:
#category.cid = 2 に紐つく product.category_id = 2 のデータを全て参照できる
print(row.pname)
【メモ】
related_name = 'product_set' とした理由は、実は related_name を定義しないと、デフォルトで product_set が定義されている状態となります。
なので、実は related_name は定義しなくても逆参照はできます。
あえて、related_name を定義する必要がある場合は、1つのテーブルに対し、リレーションが複数存在する場合はです。
その場合は related_name を以下の様に複数定義し、名前を変更する必要があります。
例)
hoge = models.ForeignKey(Hoge, related_name='hoge_set', on_delete=models.PROTECT)
foo = models.ForeignKey(Foo, related_name='foo_set', on_delete=models.PROTECT)
1 対 1 の関係
【テーブル1:category】に対して【テーブル3:category_detail】は、外部キーを持っています
category_detail.category_id は、category.cid の外部キー
この関係のとき、テーブル category_detail を検索すると category 情報も同時に抽出する様にするには、モデル category_detail を以下の様に定義する
例)
class CategoryDetail(models.Model):
class Meta:
db_table = 'category_detail'
category = models.OneToOneField(Category,verbose_name='カテゴリTBL', to_field='cid', on_delete=models.PROTECT)
detail_name = models.CharField(max_length = 100, unique = True)
del_flg = models.CharField(max_length = 1, default = '0')
【メモ】
引数 verbose_name は、参照先テーブルの論理名(日本語名)を記述する
引数 to_field は、参照先テーブルのカラム名を指定する(デフォルトでは、リレーション先のオブジェクトの主キー)
引数 on_delete は、外部キーの参照元のテーブルが削除されそうになった場合の【許可】【拒否】を指定するものです
models.PROTECT 【拒否】
models.CASCADE 【許可】 ※親のデータはもちろん、親に紐つく子のデータ全てが削除される
【注意】
変数 category のカラム名は category_id です。
外部キーは勝手に【変数名】+【_id】となります!
検索例)
res = CategoryDetail.objects.get(id=2) ※1レコードに抽出する
print(res.category.cname) ※親である Category モデルの cname を参照
print(res.category_id) ※自身の category_id を参照
【注意】
リレーションの相手がいない場合に、相手のカラムを参照しようとするとエラーとなります
【逆参照】
models.
OneToOneField を定義したモデル CategoryDetail からは、外部キーを利用して category の情報を上記の様に取得できます。
当然 category からも CategoryDetail の情報を取得でき、これを【逆参照】といいます。
逆参照をするには、モデル CategoryDetail の models.
OneToOneField に以下のパラメータを追加します。
related_name = '
categorydetail' ※
categorydetail は、任意の名前
この状態で以下の様に取得できます。
例)
res = Category.objects.get(cid=2) ※カテゴリTBLを1レコードに抽出する
print(res.categorydetail.detail_name) ※関連するカテゴリ詳細TBLのカラム detail_name を参照する
【メモ】
related_name = '
categorydetail' とした理由は、実は
related_name を定義しないと、デフォルトで
categorydetail が定義されている状態となります。(モデル名の小文字)
なので、実は
related_name は定義しなくても逆参照はできます。
あえて、
related_name を定義する必要がある場合は、1つのテーブルに対し、リレーションが複数存在する場合はです。
その場合は
related_name を以下の様に複数定義し、名前を変更する必要があります。
例)
hoge = models.OneToOneField(Hoge, related_name='hoge', on_delete=models.PROTECT)
foo = models.OneToOneField(Foo, related_name='foo', on_delete=models.PROTECT)
フィールドクラス
● クラス一覧
| フィールドの型 |
説明 |
| AutoField |
利用可能な ID に応じて、自動的にインクリメントする IntegerField です。通常は直接使う必要はありません; 指定しない場合は、主キーのフィールドが自動的にモデルに追加されます。Automatic primary key fields も参照してください。
|
| BigAutoField | 64 ビットの数値です。1 から 9223372036854775807 までの数を扱える以外は、AutoField と同じです。 |
| BigIntegerField | 64 ビットの数値です。-9223372036854775808 から 9223372036854775807 を扱える以外は IntegerField と同じです。このフィールドのデフォルトのフォームウィジェットは TextInput です。 |
| BinaryField | 生のバイナリデータを保持するためのフィールドです。bytes` のアサインメントのみをサポートします。このフィールドには機能制限があります。例えば、BinaryField の値でクエリセットをフィルタすることはできません。また、BinaryField を ModelForm に含めることもできません。 |
| BooleanField | true/false のフィールドです。 |
| CharField | 小 - 大サイズの文字列のフィールドです。 |
| DateField | Python で datetime.date インスタンスによって表される日付です。多少の追加的な省略可能な引数を持ちます: |
| DateTimeField | Python で datetime.datetime インスタンスによって表される日付と時刻です。DateField と同じくいくつかの追加的な引数を持ちます: |
| DecimalField | Python で Decimal インスタンスによって表される固定精度の小数です。2 つの 必須の 引数があります: |
| DurationField | 時刻の期間を保持するフィールドで、 Python の timedelta によってモデル化されます。PostgreSQL で使われるときに用いられるデータ型は interval で、Oracle でのデータ型は INTERVAL DAY(9) TO SECOND(6)です。 それ以外では、マイクロ秒のbigint が使われます。 |
| EmailField | 値が有効な E メールアドレスかチェックする CharField です。EmailValidator を使ってインプットを検証します。 |
| FileField | ファイルアップロードのフィールドです。 |
| FileField と FieldFile | モデル上の FileField にアクセスするとき、元となるファイルにアアクセスするためのプロキシとして、FieldFile のインスタンスが与えられます。 |
| FilePathField | ファイルシステム上の特定のディレクトリ内のファイル名に選択肢が制限されている CharField です。3 つの特別な引数があり、最初の 1 つは 必須 です: |
| FloatField | float インスタンスによって表される Python の浮動小数点数です。 |
| ImageField | FileField から全ての属性とメソッドを継承して、さらにアップロードされたオブジェクトが有効な画像であることを検証します。 |
| IntegerField | 数値です。-2147483648 から 2147483647 までの値は、Django でサポートされているデータベース内では安全です。このフィールドのデフォルトのフォームウィジェットは、localize が False のときには NumberInput で、そうでなければ TextInput となります。 |
| GenericIPAddressField | IPv4 か IPv6 のアドレスで、文字列フォーマットです (例: 192.0.2.30 ないし 2a02:42fe::4)。このフィールドのデフォルトのフォームウィジェットは TextInput です。 |
| NullBooleanField | BooleanField とほぼ同じですが、オプションの 1 つとして NULL を許容します。BooleanField を null=True で使う代わりにこれを使ってください。このフィールドのデフォルトのフォームウィジェットは NullBooleanSelect です。 |
| PositiveIntegerField | IntegerField とほぼ同じですが、正の値かゼロ (0) でなければなりません。Django によってサポートされる全てのデータベースで、0 から 2147483647 までの値は安全です。後方互換性の理由から、値 0 が有効となっています。 |
| PositiveSmallIntegerField | PositiveIntegerField とほぼ同じですが、特定の (データベースに依存した) ポイントより下の値のみを許容します。Django でサポートされている全てのデータベースで、0 から 32767 までの値は安全です。 |
| SlugField | Slug は新聞の用語です。 スラグは、文字、数字、アンダースコア、またはハイフンのみを含む短いラベルです。 一般的に URL 内で使用されます。 |
| SmallIntegerField | IntegerField とほぼ同じですが、特定の (データベースに依存した) ポイントより下の値のみを許容します。Django でサポートされている全てのデータベースで、-32768 から 32767 までの値は安全です。 |
| TextField | 多量のテキストのフィールドです。このフィールドのデフォルトのフォームウィジェットは Textarea です。 |
| TimeField | Python で datetime.time インスタンスによって表される時刻です。DateField と同じ自動入力されるオプションを受け入れます。 |
| URLField | URL のための CharField です。 |
| UUIDField | UUID (Universally Unique Identifier) を保持するためのフィールドです。Python’s UUID クラスを使います。 PostgreSQL 上で使われるとき、uuid データ型の中に保持します。それ以外は char(32) の中に保持します。 |
● クラスのオプション
| フィールドオプション |
説明 |
| null |
Trueの場合、Django はデータベース内に NULL として空の値を保持します。デフォルトは False です。
|
| blank | True の場合、フィールドはブランクになることが許容されます。デフォルトは False です。 |
| choices | フィールドに対する選択肢として使うための 2 項目の iterable 自体で構成される ([(A, B), (A, B) ...]) iterable (例: リストやタプル) です。これが与えられた場合は、デフォルトのフォームウィジェットは、標準のテキストフィールドの代わりに、選択肢を伴ったセレクトボックスになります。 |
| db_column | このフィールドに使用するデータベース列の名前。 これが与えられなければ、Djangoはフィールドの名前を使用します。 |
| db_index | True の場合、データベースインデックスがこのフィールドのために生成されます。 |
| db_tablespace | このフィールドの索引に使用するデータベースのテーブル領域の名前(このフィールドが索引付けされている場合)。 デフォルトでは、プロジェクトのDEFAULT_INDEX_TABLESPACE設定(設定されている場合)またはモデルのdb_tablespace(存在する場合)です。 バックエンドが索引のテーブルスペースをサポートしていない場合、このオプションは無視されます。 |
| default | そのフィールドのデフォルト値です。このオプションには特定の値もしくは呼び出し可能オブジェクトを渡すことができます。もし渡した値が呼び出し可能であれば新しくオブジェクトが生成される度に呼び出されます。 |
| editable | Falseの場合、フィールドは管理者または他のModelFormに表示されません。 モデルの検証中もスキップされます。 デフォルトはTrueです。 |
| error_messages | error_messages引数を使用すると、フィールドが生成するデフォルトのメッセージを上書きできます。 オーバーライドするエラーメッセージに一致するキーを持つ辞書を渡します。 |
| help_text | フォームウィジェットと共に表示される 「補助」 テキストになります。この値はフィールドがフォームとして利用されない場合でもドキュメント化する際に有用です。 |
| primary_key | True の場合、設定したフィールドはそのモデルの主キーとなります。 |
| unique | True の場合、そのフィールドはテーブル上で一意となる制約を受けます。 |
| unique_for_date | これをDateFieldまたはDateTimeFieldの名前に設定し、このフィールドが日付フィールドの値に対して一意であることを要求します。 |
| unique_for_month | unique_for_dateと同様ですが、フィールドはその月に関してユニークである必要があります。 |
| unique_for_year | unique_for_dateやunique_for_monthと同様です。 |
| verbose_name | 人間が判読可能なフィールド名。 冗長な名前が与えられていない場合、Djangoはそのフィールドの属性名を使って自動的に作成し、アンダースコアをスペースに変換します。 Verboseフィールド名を参照してください。 |
| validators | このフィールドで実行するバリデータのリスト。 詳細については、バリデータのドキュメントを参照してください。 |
【重要】
Django は複合主キーを持つことが出来ない!
これを回避するには、捨て主キーを適当に定義し、後は複合ユニークキーを設定するしかない。
複合ユニークキーを設定するには class Meta に記述する
例)
class Hoge(models.Model):
class Meta:
db_table = 'hoge_tbl'
unique_together = (('foo', 'bar', 'fuga'),)
その他 便利アクセス
● 定義したフィールド名を取得する
#定義したフィールドをループで回せる
for v in Hoge._meta.fields
#フィールド名
print(v.name)
#直接リスト型にするのもアリ!
[v.name for v in Books._meta.fields]