LoginSignup
16
9

More than 3 years have passed since last update.

DjangoのChoiceFieldを列挙型で指定する

Posted at

DjangoのmodelsにおけるTextFieldIntegerField、そしてformsにおけるChoiceFieldに用いるchoicesには、これまでは以下のような形式の値が必要でした。

YEAR_IN_SCHOOL_CHOICES = [
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
]

Django3.0からはTextChoicesIntegerChoicesというクラスが追加され、以下のような書き方が出来るようになりました。

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

TextChoicesIntegerChoicesEnumクラスを継承しているので、それに近い感覚で書くことが出来るようになりました。

もちろんただ列挙型として扱うことが出来るだけでなく、ラベル(フォームで表示される文字列、各タプルの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'

アンダースコア(_)を半角スペースに変換し、タイトルケース(各単語の先頭を大文字にする)を適用してラベルにするようです。

公式ドキュメント

16
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
9