When defining choices for CharField or TextField in Django models, we often used a list of tuples.
However, by utilizing the TextChoices introduced in Django 3.0, we can write cleaner and more meaningful code.


1. Defining Model Choices: Traditional Approach

The common approach we use is the list of tuples method, as shown below.

# 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')

Drawbacks of the Traditional Approach: - It's hard to understand the meaning of the code (e.g., it’s difficult to immediately know what 'DF' means) - Although get_FIELD_display() is used, it’s not structured like an Enum, making maintenance inconvenient - Hardcoding is necessary in conditional comparisons

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

2. Improving with the TextChoices Method


The principle is simple when you look at the source code, so those curious about how it works are encouraged to check out the Django source code.
Here, I will simply explain how to use it.

# Inside 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)

Advantages of This Approach: - You can handle conditions with meaningful names like PostStatus.DRAFT - Full support for get_status_display() - Can be treated as objects like enums, benefiting from IDE autocompletion and static analysis

if post.status == PostStatus.DRAFT:
    ...
  • Reusability: If the same choices need to be shared across multiple models, they can be defined in an external file (choices.py)

Essentially, reusability is the main advantage of using the TextChoices class. If it's a choice used commonly across various Django apps, you can place it in a file like commons/choices.py and use it from any app.


3. Conclusion


Django's TextChoices is an excellent feature that helps handle model choices in a more intuitive and robust manner.
Step away from the old tuple list method and elevate your code quality!