Djangoのmodels
におけるTextField
やIntegerField
、そしてforms
におけるChoiceField
に用いるchoices
には、これまでは以下のような形式の値が必要でした。
YEAR_IN_SCHOOL_CHOICES = [
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
]
Django3.0からはTextChoices
とIntegerChoices
というクラスが追加され、以下のような書き方が出来るようになりました。
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', 'Freshman'
SOPHOMORE = 'SO', 'Sophomore'
JUNIOR = 'JR', 'Junior'
SENIOR = 'SR', 'Senior'
GRADUATE = 'GR', 'Graduate'
YEAR_IN_SCHOOL_CHOICES = YearInSchool.choices
TextChoices
やIntegerChoices
はEnum
クラスを継承しているので、それに近い感覚で書くことが出来るようになりました。
もちろんただ列挙型として扱うことが出来るだけでなく、ラベル(フォームで表示される文字列、各タプルの2要素目の値)の値も保持しています。
プロパティ
names
, values
, FIELD.name
, FIELD.value
>>> YearInSchool.names
['FRESHMAN', 'SOPHOMORE', 'JUNIOR', 'SENIOR', 'GRADUATE']
>>> YearInSchool.values
['FR', 'SO', 'JR', 'SR', 'GR']
>>> YearInSchool.FRESHMAN.name
'FRESHMAN'
>>> YearInSchool.FRESHMAN.value
'FR'
name
では列挙型のフィールド名が、value
ではDBに格納される文字列が返されます。
これはEnum
の実装によるものです。
labels
, FIELD.label
>>> YearInSchool.labels
['Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate']
>>> YearInSchool.FRESHMAN.label
'Freshman'
ラベルが返されます。モデルのフィールドに対してはget_FOO_display
(FOO
はフィールド名)というプロパティが自動生成され、これを呼び出すことでもラベルが取得できます。
choices
>>> YearInSchool.choices
[('FR', 'Freshman'), ('SO', 'Sophomore'), ('JR', 'Junior'), ('SR', 'Senior'), ('GR', 'Graduate')]
以前のchoices
で指定する形式でのタプルのリストが返されます。
文字列からラベルを取得する
>>> YearInSchool('FR').label
'Freshman'
>>> YearInSchool['FRESHMAN'].label
'Freshman'
上記のようにしてEnum
のフィールドを取得し、name
, value
, label
が取得可能です
ラベルを指定しない場合
class Vehicle(models.TextChoices):
CAR = 'C'
TRUCK = 'T'
JET_SKI = 'J'
>>> Vehicle.JET_SKI.label
'Jet Ski'
アンダースコア(_
)を半角スペースに変換し、タイトルケース(各単語の先頭を大文字にする)を適用してラベルにするようです。
公式ドキュメント