Enum in Django

Enumerations are a powerful communication method to map a domain concept to code.

Enumerations in Python

An Enum type is a container for a related set of named constants.

For example, look at the http.HTTPStatus Enum in Python's standard library.

With an Enum:

  • it becomes harder to introduce typos
  • you can clearly communicate your intent

Django enumeration types

Django provides customized enumeration types that you can subclass to define choices.

The Django's documentation uses an inner class — a pattern used at different places.

Here's a flat example for brevity:

from django.db import models

class Status(models.TextChoices):
    DRAFT = "d", "Draft"
    PUBLISHED = "p", "Published"
    HIDDEN = "h", "Hidden"

Status.choices
# [('d', 'Draft'), ('p', 'Published'), ('h', 'Hidden')]

dict(Status.choices)
# {'d': 'Draft', 'p': 'Published', 'h': 'Hidden'}

Status.values
# ['d', 'p', 'h']

Status.labels
# ['Draft', 'Published', 'Hidden']

Status.DRAFT.value
# 'd'

Status.DRAFT.label
# 'Draft'

str(Status.DRAFT) == Status.DRAFT.value
# True

You can use the index syntax to get a member by name:

Status["DRAFT"]
# Status.DRAFT

You can use the call syntax to get a member by value:

Status("d")
# Status.DRAFT

Structural pattern matching

As of Python 3.10, structural pattern matching works with enums:

match item.status:
    case Status.DRAFT:
        print("It's a draft!")
    case Status.PUBLISHED:
        print("It's published!")
    case Status.HIDDEN:
        print("It's hidden!")

Further reading

You can do a lot more useful things with Enum:

Avant Any software project has a complexity budget Après HTML form serialization

A Kemar Joint