
Security News
The Nightmare Before Deployment
Season’s greetings from Socket, and here’s to a calm end of year: clean dependencies, boring pipelines, no surprises.
django-enum
Advanced tools
🚨 See migration guide for notes on 1.x to 2.x migration. 🚨
Full and natural support for PEP435 enumerations as Django model fields.
Many packages aim to ease usage of Python enumerations as model fields. Most were superseded when Django provided TextChoices and IntegerChoices types. The motivation for django-enum was to:
django-enum provides a new model field type, EnumField, that allows you to treat almost any PEP435 enumeration as a database column. EnumField resolves the correct native Django field type for the given enumeration based on its value type and range. For example, IntegerChoices that contain values between 0 and 32767 become PositiveSmallIntegerField.
from django.db import models
from django_enum import EnumField
class MyModel(models.Model):
class TextEnum(models.TextChoices):
VALUE0 = 'V0', 'Value 0'
VALUE1 = 'V1', 'Value 1'
VALUE2 = 'V2', 'Value 2'
class IntEnum(models.IntegerChoices):
ONE = 1, 'One'
TWO = 2, 'Two',
THREE = 3, 'Three'
# this is equivalent to:
# CharField(max_length=2, choices=TextEnum.choices, null=True, blank=True)
txt_enum = EnumField(TextEnum, null=True, blank=True)
# this is equivalent to
# PositiveSmallIntegerField(choices=IntEnum.choices, default=IntEnum.ONE.value)
int_enum = EnumField(IntEnum, default=IntEnum.ONE)
EnumField is more than just an alias. The fields are now assignable and accessible as their enumeration type rather than by-value:
instance = MyModel.objects.create(
txt_enum=MyModel.TextEnum.VALUE1,
int_enum=3 # by-value assignment also works
)
assert instance.txt_enum == MyModel.TextEnum('V1')
assert instance.txt_enum.label == 'Value 1'
assert instance.int_enum == MyModel.IntEnum['THREE']
assert instance.int_enum.value == 3
Flag types are also seamlessly supported! This allows a database column to behave like a bit field and is an alternative to having multiple boolean columns. There are positive performance implications for using a bit field instead of booleans proportional on the size of the bit field and the types of queries you will run against it. For bit fields more than a few bits long the size reduction both speeds up queries and reduces the required storage space. See the documentation for discussion and benchmarks.
class Permissions(IntFlag):
READ = 1 << 0
WRITE = 1 << 1
EXECUTE = 1 << 2
class FlagExample(models.Model):
permissions = EnumField(Permissions)
FlagExample.objects.create(permissions=Permissions.READ | Permissions.WRITE)
# get all models with RW:
FlagExample.objects.filter(permissions__has_all=Permissions.READ | Permissions.WRITE)
django-enum supports enum types that do not derive from Django's IntegerChoices and TextChoices. This allows us to use other libs like enum-properties which makes possible very rich enumeration fields:
?> pip install enum-properties
from enum_properties import StrEnumProperties
from django.db import models
class TextChoicesExample(models.Model):
class Color(StrEnumProperties):
# attribute type hints become properties on each value,
# and the enumeration may be instantiated from any symmetric
# property's value
label: Annotated[str, Symmetric()]
rgb: Annotated[t.Tuple[int, int, int], Symmetric()]
hex: Annotated[str, Symmetric(case_fold=True)]
# properties specified in type hint order after the value
# name value label rgb hex
RED = "R", "Red", (1, 0, 0), "ff0000"
GREEN = "G", "Green", (0, 1, 0), "00ff00"
BLUE = "B", "Blue", (0, 0, 1), "0000ff"
color = EnumField(Color)
instance = TextChoicesExample.objects.create(
color=TextChoicesExample.Color('FF0000')
)
assert instance.color == TextChoicesExample.Color('Red')
assert instance.color == TextChoicesExample.Color('R')
assert instance.color == TextChoicesExample.Color((1, 0, 0))
# direct comparison to any symmetric value also works
assert instance.color == 'Red'
assert instance.color == 'R'
assert instance.color == (1, 0, 0)
# save by any symmetric value
instance.color = 'FF0000'
# access any enum property right from the model field
assert instance.color.hex == 'ff0000'
# this also works!
assert instance.color == 'ff0000'
# and so does this!
assert instance.color == 'FF0000'
instance.save()
# filtering works by any symmetric value or enum type instance
assert TextChoicesExample.objects.filter(
color=TextChoicesExample.Color.RED
).first() == instance
assert TextChoicesExample.objects.filter(color=(1, 0, 0)).first() == instance
assert TextChoicesExample.objects.filter(color='FF0000').first() == instance
While they should be unnecessary if you need to integrate with code that expects an interface fully compatible with Django's TextChoices and IntegerChoices django-enum provides TextChoices, IntegerChoices, FlagChoices and FloatChoices types that derive from enum-properties and Django's Choices. So the above enumeration could also be written:
from django_enum.choices import TextChoices
class Color(TextChoices):
# label is added as a symmetric property by the base class
rgb: Annotated[t.Tuple[int, int, int], Symmetric()]
hex: Annotated[str, Symmetric(case_fold=True)]
# name value label rgb hex
RED = "R", "Red", (1, 0, 0), "ff0000"
GREEN = "G", "Green", (0, 1, 0), "00ff00"
BLUE = "B", "Blue", (0, 0, 1), "0000ff"
pip install django-enum
django-enum has several optional dependencies that are not installed by default. EnumField works seamlessly with all Django apps that work with model fields with choices without any additional work. Optional integrations are provided with several popular libraries to extend this basic functionality, these include:
> pip install "django-enum[properties]"
Like with Django, PostgreSQL is the preferred database for support. The full test suite is run against all combinations of currently supported versions of Django, Python, and PostgreSQL as well as psycopg3 and psycopg2. The other RDBMS supported by Django are also tested including SQLite, MySQL, MariaDB and Oracle. For these RDBMS (with the exception of Oracle, tests are run against the minimum and maximum supported version combinations to maximize coverage breadth.
See the latest test runs for our current test matrix
For Oracle, only the latest version of the free database is tested against the minimum and maximum supported versions of Python, Django and the cx-Oracle driver.
Consider using django-render-static to make your enumerations DRY across the full stack!
Please report bugs and discuss features on the issues page.
Contributions are encouraged!
FAQs
Full and natural support for enumerations as Django model fields.
We found that django-enum demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Season’s greetings from Socket, and here’s to a calm end of year: clean dependencies, boring pipelines, no surprises.

Research
/Security News
Impostor NuGet package Tracer.Fody.NLog typosquats Tracer.Fody and its author, using homoglyph tricks, and exfiltrates Stratis wallet JSON/passwords to a Russian IP address.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.