django-enumfields
django-enumfields provides robust integration of Python's `enum.Enum` types with Django models, forms, and REST Framework serializers. It's currently at version 2.1.1 and follows a moderate release cadence, primarily focusing on Django and Python version compatibility and bug fixes.
Common errors
-
ValueError: Field 'my_field' does not allow value 'some_string_value'.
cause Attempting to assign a raw string or an invalid value directly to an `EnumField` or `EnumIntegerField` instance. These fields expect an actual `enum.Enum` member.fixAssign an `enum.Enum` member directly, e.g., `model_instance.my_field = MyEnum.FIRST`. If dealing with string input, convert it to an enum member first, e.g., `MyEnum[input_string.upper()]` or `MyEnum(int(input_string))`. -
django.core.exceptions.ValidationError: ['Enter a valid value.']
cause Submitting a form with a value for an EnumField that does not correspond to any valid enum member's name or value.fixEnsure the form input for enum fields precisely matches either the `.name` or `.value` of a valid `enum.Enum` member defined for that field. -
AttributeError: 'NoneType' object has no attribute 'name'
cause Accessing `.name` or `.value` on an `EnumField` instance when its value is `None` (i.e., the database field is null and the field is not set).fixIf the field can be null, define it with `null=True` (e.g., `EnumField(MyEnum, null=True)`). When accessing, always check for `None` first: `if instance.my_field: print(instance.my_field.name)`.
Warnings
- breaking Version 2.0.0 dropped support for Python 2.7, 3.4 and Django 1.8, 1.10. Ensure your project meets the new minimum requirements.
- breaking Version 2.1.0 dropped support for Django 2.0 and 2.1. Projects on these Django versions must upgrade Django or stick to older `django-enumfields` versions.
- gotcha A regression in version 2.1.0 mistakenly broke string-to-enum conversion, potentially causing `ValueError` or incorrect data when loading models or deserializing data where string values were expected.
- gotcha `EnumCharField` requires `max_length` just like a standard Django `CharField`. Forgetting it will result in `FieldError` or `SystemCheckError`.
Install
-
pip install django-enumfields
Imports
- EnumField
from enumfields import EnumField
- EnumIntegerField
from enumfields import EnumIntegerField
- EnumCharField
from enumfields import EnumCharField
Quickstart
import enum
from django.db import models
from enumfields import EnumField, EnumIntegerField, EnumCharField
class MyEnum(enum.Enum):
FIRST = 1
SECOND = 2
THIRD = 3
class MyCharEnum(enum.Enum):
FOO = 'foo'
BAR = 'bar'
class MyModel(models.Model):
# Stores the enum value as its internal integer value
my_int_field = EnumIntegerField(MyEnum, default=MyEnum.FIRST)
# Stores the enum value as its internal value (can be mixed types)
my_field = EnumField(MyEnum, default=MyEnum.FIRST)
# Stores the enum value as a string (requires max_length)
my_char_field = EnumCharField(MyCharEnum, max_length=10, default=MyCharEnum.FOO)
def __str__(self):
return f'{self.my_int_field.name} - {self.my_char_field.value}'
# Example usage:
# instance = MyModel.objects.create(my_int_field=MyEnum.SECOND, my_char_field=MyCharEnum.BAR)
# print(instance.my_int_field) # MyEnum.SECOND
# print(instance.my_int_field.value) # 2
# print(instance.my_char_field.name) # FOO