Django Choices Field

raw JSON →
4.0.0 verified Fri May 01 auth: no python

A Django field that directly sets/gets Django's TextChoices/IntegerChoices enum values, eliminating manual conversion between enum members and database values. Version 4.0.0 requires Python >=3.10, Django <4.0, and drops support for Python 3.8/3.9. Released irregularly, with breaking changes in v4.0.0 including strict blank/null validation and type checking utilities.

pip install django-choices-field
error django.core.exceptions.ImproperlyConfigured: ChoicesField 'status' cannot have blank=True without also having null=True
cause Since v4.0.0, blank=True requires null=True to avoid empty string ambiguity with non-string choices.
fix
Add null=True to the field definition, e.g., status = ChoicesField(choices_enum=Status, blank=True, null=True)
error TypeError: 'Status' object is not iterable
cause Trying to iterate over a single enum member instead of using .choices or .values.
fix
Use Status.choices if you need the tuple of choices, or iterate over Status directly: for member in Status: ...
error django.core.exceptions.ValidationError: ['"invalid" is not a valid choice.']
cause Passing a raw value that is not part of the enum, or missing the enum member conversion.
fix
Assign enum members, e.g., obj.status = MyModel.Status.PUBLISHED, not obj.status = 'PUBLISHED'. For form submission, ensure the form field is also using choices_enum.
breaking In v4.0.0, passing blank=True without null=True raises ImproperlyConfigured. Previously it was allowed but could cause data integrity issues.
fix Always set null=True when blank=True, or omit blank=True if not needed.
deprecated Passing choices as a plain list/tuple in the field constructor is deprecated and will be removed in a future version. Use choices_enum instead.
fix Define a ChoicesEnum subclass and pass it to the choices_enum parameter.
gotcha The get_FIELD_display() method works out of the box, but in versions prior to 3.1.1 it was broken for enum fields (returned value instead of label).
fix Upgrade to >=3.1.1, or manually override get_FIELD_display() if stuck on older version.
gotcha ChoicesField does not support null=False and blank=False if the enum does not have a default; you must either set a default or allow null/blank.
fix Provide a default argument (e.g., default=MyEnum.FOO) or set null=True and/or blank=True.

Define a model with a ChoicesField using Django's TextChoices enum.

from django.db import models
from django.utils.translation import gettext_lazy as _
from choices_field import ChoicesField

class MyModel(models.Model):
    class Status(models.TextChoices):
        DRAFT = 'DRAFT', _('Draft')
        PUBLISHED = 'PUBLISHED', _('Published')

    status = ChoicesField(choices_enum=Status, default=Status.DRAFT)

obj = MyModel(status=MyModel.Status.PUBLISHED)
print(obj.status)  # MyModel.Status.PUBLISHED
print(obj.status.value)  # 'PUBLISHED'