Install & Compatibility
Where this runs
tested against v2.4.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.645s · 66.5MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 3.5s · import 0.570s · 67MB
66MB installed
● package 66MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
EnumField
✓ from django_enum import EnumField
Choices
✓ from enum_properties import Choices
✗ from django.db.models import Choices
`django-enum` leverages `enum_properties.Choices` for its enhanced features and integration, not Django's built-in `Choices` metaclass. Using the latter will lack `django-enum`'s functionality.
Flag
✓ from enum_properties import Flag
p
✓ from enum_properties import p
Helper function from `enum-properties` for defining enum members with multiple properties (e.g., value and label) concisely.
Demonstrates defining an `enum_properties.Choices` enum and integrating it as an `EnumField` in a Django model. Includes minimal Django setup, simplified migrations, model creation, and filtering by enum member and value. This example shows how to correctly use the `p()` helper for robust enum definitions.
import os
import django
from django.conf import settings
from django.db import models
from enum_properties import Choices, p
from django_enum import EnumField
# Minimal Django settings for a runnable example
settings.configure(
DEBUG=True,
INSTALLED_APPS=["django.contrib.auth", "django.contrib.contenttypes", "myapp"],
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
# Ensure 'myapp' is recognized by Django for migrations
TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }],
ROOT_URLCONF='django_enum.urls' # Dummy, or define a minimal one if needed
)
django.setup()
# Define an enum using enum_properties.Choices and the p() helper
class Status(Choices):
PENDING = p('P', 'Pending')
APPROVED = p('A', 'Approved')
REJECTED = p('R', 'Rejected')
# Define a Django model using EnumField
class Order(models.Model):
name = models.CharField(max_length=100)
status = EnumField(Status, default=Status.PENDING)
class Meta:
app_label = 'myapp' # Required for standalone model in Django setup
def __str__(self):
return f"Order '{self.name}' - Status: {self.status.label}"
# Example usage:
if __name__ == '__main__':
# Apply migrations (simplified for quickstart without manage.py)
from django.core.management import call_command
from django.db.migrations.executor import MigrationExecutor
from django.db import connection
# Django needs to discover the models for migration, so we manually register an app
from django.apps import apps
apps.populate(settings.INSTALLED_APPS)
executor = MigrationExecutor(connection)
executor.loader.build_graph()
targets = executor.loader.graph.leaf_nodes()
executor.migrate(targets)
print('Migrations applied for myapp.')
# Create an instance
order1 = Order.objects.create(name='Laptop', status=Status.PENDING)
order2 = Order.objects.create(name='Keyboard', status=Status.APPROVED)
print(f"Created: {order1}")
print(f"Created: {order2}")
# Retrieve and interact with the enum field
retrieved_order = Order.objects.get(name='Laptop')
print(f"Retrieved order status (name): {retrieved_order.status.name}")
print(f"Retrieved order status (value): {retrieved_order.status.value}")
print(f"Retrieved order status (label): {retrieved_order.status.label}")
# Filtering by enum member
approved_orders = Order.objects.filter(status=Status.APPROVED)
print(f"Approved orders: {[str(o) for o in approved_orders]}")
# Filtering by enum value
pending_orders = Order.objects.filter(status__value='P')
print(f"Pending orders (by value): {[str(o) for o in pending_orders]}")
Debug
Known issues
breakingVersions of `django-enum` 2.3.0 and above dropped support for Django versions 3.2-4.1 and Python 3.9. Running these newer versions in older environments will cause `ImproperlyConfigured` or `ModuleNotFoundError` errors.fixUpgrade your Django installation to 4.2 or higher, and your Python version to 3.10 or higher to use `django-enum` 2.3.0+. For older environments, you must pin to a `django-enum` version `<2.3.0`.
affects: >=2.3.0
gotchaWhen defining `enum_properties.Choices` (or `Flag`) members, tuple values (e.g., `NAME = ('value', 'Label')`) are NOT automatically unpacked into `value` and `label` properties as they might be with Django's native `Choices`. The member's value will literally be the tuple.fixAlways use the `enum_properties.p()` helper function to explicitly define value and label properties for enum members. For example, `STATUS = p('S', 'Status Label')` ensures correct property assignment. affects: All versions
gotchaEnumField values may not display correctly or filter as expected in the Django Admin's `list_display` or `list_filter` if the underlying `enum-properties` enum members lack proper hash equivalency (`__hash__` and `__eq__` methods).fixEnsure your custom `enum_properties.Choices` or `Flag` definitions correctly implement `__hash__` and `__eq__` methods, especially if you define custom properties beyond simple `value` and `label`. Typically, relying on the default `enum.Enum` behavior (which uses `value` for hashing/equality) or carefully constructing `enum-properties` will mitigate this.
affects: All versions, particularly problematic prior to v2.2.3 documentation enhancements
Errors
Common errors & fixes
django.core.exceptions.ImproperlyConfigured: django-enum requires Django 4.2 or higher. (or similar error for Python version incompatibility)
Attempting to use `django-enum` version 2.3.0 or later with an unsupported Django (<4.2) or Python (<3.10) version.
fixUpgrade your Django installation to 4.2+ and your Python version to 3.10+. Alternatively, if upgrading is not feasible, downgrade `django-enum` to a compatible version (e.g., `pip install django-enum<2.3.0`).
TypeError: 'tuple' object cannot be interpreted as an integer (or similar TypeError when accessing enum member properties like `.label`)
You defined an `enum_properties.Choices` member with a raw tuple, such as `STATUS = ('P', 'Pending')`, instead of using the `p()` helper. This makes the member's value the tuple itself, preventing correct property access.
fixModify your enum definition to use `enum_properties.p()` for members that require distinct value and label properties. Example: `from enum_properties import p; class MyStatus(Choices): PENDING = p('P', 'Pending')`. AttributeError: 'str' object has no attribute 'name' (or '.label' or '.value') when accessing enum field
This usually happens when you're mistakenly trying to access enum properties on the raw string value stored in the database, rather than the `EnumField` instance itself, or if the field somehow isn't converting the database value back to an enum member.
fixEnsure you are accessing the field correctly on the model instance (e.g., `my_model.status.label`) and that `django-enum` is properly installed and configured in `INSTALLED_APPS`.
Upgrade
Version history
2.4.3latest on PyPI · released May 31, 2026
Audit
Dependencies
enum-propertiesrequiredCore functionality for advanced enum definition and properties, which django-enum builds upon.
djangorequiredRequired for integration with Django models and ORM.
django-stubsoptionalEnables full type hinting for EnumField's when installed alongside Django stubs.