Django Enum

2.4.2 · active · verified Fri Apr 17

Django Enum provides full and natural support for enumerations as Django model fields, integrating with `enum-properties`. It allows defining robust enum fields that seamlessly store and retrieve enum members in the database, offering advanced features like properties and flags. As of version 2.4.2, it supports Django 4.2+ and Python 3.10+, with regular patch and minor releases.

Common errors

Warnings

Install

Imports

Quickstart

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]}")

view raw JSON →