This is a preview at a secret URL that can be shared with trusted people. It will update with changes automatically. View the published version .

August 18, 2016

Python 3.4 introduced enums types which seem tailor made for use with django model choices. For some reason there seemed no examples to do this, but it’s relatively simple with some tricks (you may call them warts, django needs to enable this better). These have been back ported to prior python versions via the enum34 package (“pip install enum34”).

In this example, we’ll use an IntEnum to associate a variable with an integer value. For django, this means that the database contains integers, though we have a descriptive text for each choice. This is desirable, as we can abstract the name of the variable from the actual value. If you change / refactor the name, the existing values will simply remain the same.

Here’s the model definition:

from enum import IntEnum, unique def django_enum(cls): # decorator needed to enable enums in django templates cls.do_not_call_in_templates = True return cls class MyModel(Model): # store the choices in the model, so that they are readily # accessible wherever the model is. # unique ensures all variables are unique @unique @django_enum class MyChoices(IntEnum): ready = 0 set = 10 go = 20 complete = 100 # transform enum into choices conform format [(value, str)] # also replacing underscore with a space for readability status = IntegerField(choices=[(choice.value, choice.name.replace("_", " ")) for choice in MyChoices])

You can now access this in your template as you would expect:

{% if mymodel.status == mymodel.MyChoices.ready %} We are ready! {{ mymodel.MyChoices.ready.name }} {% elif mymodel.status >= mymodel.MyChoices.set %} Set, go or complete: {{ mymodel.get_status_display }} {% endif %}

In python, the enums can be accessed by their value or their name:

# let's display the name MyModel.MyChoices.ready.name # let's display the value MyModel.MyChoices.ready.value # python will automatically compare the int value when comparing. This returns True MyModel.MyChoices.ready == 0 # this will return 'MyChoices.ready' str(MyModel.MyChoices.ready)

That’s all I’ve needed so far. Read up more on the official docs at

https://docs.python.org/3/library/enum.html and let me know if this can be improved in any way!

If you want to know why you need the django_enum decorator, read this:

http://stackoverflow.com/questions/35953132/how-to-access-enum-types-in-django-templates

39 Kudos