Monthly Archives: February 2014

How to use Enums for Django Field.choices

In Django when using the choices parameter on a form field the format passed in must be as follows:

# within your models.Model class...
STUDENT_TYPE_CHOICES = (
    ('0', 'freshman'),
    ('1', 'sophomore'),
    ('2', 'junior'),
    ('3', 'senior'),
)
student_type = models.CharField(max_length=1, choices=STUDENT_TYPE_CHOICES)

This means elsewhere in your code if you want to specify a choice field value, you’d have to enter the first slot of the tuple’s value, e.g.:

junior_students = Student.objects.filter(student_type='2')

This is pretty terrible since it’s hardcoded in our source, possibly over many files.

How to fix this mess:

In my project I added common/utils.py containing the following:

from enum import Enum

class ChoiceEnum(Enum):
    @classmethod
    def choices(cls):
        return tuple((i.name, i.value) for i in cls)

That’s the hard work over.

Now when you create your field with choices:

from common.utils import ChoiceEnum

class StudentTypes(ChoiceEnum):
    freshman = 0
    sophomore = 1
    junior = 2
    senior = 3

# within your models.Model class...
class Student(models.Model):
    student_type = models.CharField(max_length=1, choices=StudentTypes.choices())

 

Now if we need to access StudentTypes from elsewhere in our source code, we can simply:

junior_students = Student.objects.filter(student_type=StudentTypes.junior.value)

 

That’s it. If anyone knows of a nicer way feel free to comment below.