The problem with supplying a Django model field with choices parameter is the way you check a value of that field in an object. You do nasty things like this:
if model_instance.choice_field == 1:
The problem of getting rid of hard-coded numbers is recognized over the internet, but I haven’t found any short and understandable solution. The solution to this problem needs to work like this:
>>> states = Enum('OPEN', 'CLOSED')
>>> states.OPEN
0
>>> states.get_choices()
((0, 'OPEN'), (1, 'CLOSED'))
Basically, we need a enumeration in python, that is ok to use as the Django choices
model field argument. The code I’ve came up with is pretty short:
class DjangoEnum(object):
def __init__(self, *string_list):
self.__dict__.update([(string, number) for (number, string)
in enumerate(string_list)])
def get_choices(self):
return tuple(enumerate(self.__dict__.keys()))
Of course, this only works if you use integers in your model. I use models.PositiveSmallIntegerField
with this.
UPD. Also posted it to DjangoSnippets