Djangoモデルで CharFieldTextFieldの選択肢を定義する際、よくタプルリストを使用してきました。
しかし、Django 3.0から導入された TextChoicesを活用することで、もっと クリーンで、意味のあるコードを書くことが可能になります。


1. モデル選択肢定義:従来の方法

私たちが使いやすい方法は、以下のようにタプルリスト方式です。

# models.py
STATUS_CHOICES = [
    ('DF', 'Draft'),
    ('PB', 'Published'),
    ('AR', 'Archived'),
]

class Post(models.Model):
    status = models.CharField(max_length=2, choices=STATUS_CHOICES, default='DF')

従来の方法の欠点: - コードの意味を理解しにくい ('DF'が何を指すのかすぐわからない) - get_FIELD_display()は使えますが、Enumスタイルに構造化されていないためメンテナンスが不便 - 条件比較などでハードコーディングが必要になる

if post.status == 'DF':
    ...

2. TextChoices方式での改善


ソースコードを見ると原理は簡単なので、動作原理が気になる方はDjangoのソースコードを参照することをお勧めします。
ここでは単に使い方について説明したいと思います。

# models.py の中
from django.db import models

class PostStatus(models.TextChoices):
    DRAFT = 'DF', 'Draft'
    PUBLISHED = 'PB', 'Published'
    ARCHIVED = 'AR', 'Archived'

class Post(models.Model):
    status = models.CharField(max_length=2, choices=PostStatus.choices, default=PostStatus.DRAFT)

この方法の利点: - PostStatus.DRAFTのように意味のある名前で条件処理が可能 - get_status_display()が完全サポート - enumのようにオブジェクトとして扱えるため、IDEのオートコンプリートや静的解析に便利

if post.status == PostStatus.DRAFT:
    ...
  • 再利用性: 複数のモデルで同じ選択肢を共有する必要がある場合は、外部ファイル(choices.py)に定義すればよい

実質的に 再利用性がこの TextChoiceクラスを使う最大の利点だと思います。 DjangoのさまざまなAppで共通に使用する選択肢であれば、commons/choices.pyなどに入れておけば、どのアプリでも選択肢を呼び出すことができます。


3. 結論


Djangoの TextChoicesはモデル選択肢をより 直感的で堅牢に扱う手助けをする素晴らしい機能です。
過去のタプルリスト方式を脱却し、コードの品質を一段階引き上げてみてください!