I have a model class of which I want two fields to be a choice fields, so to populate those choices I am using an enum as listed below
#models.py class Transaction(models.Model): trasaction_status = models.CharField(max_length=255, choices=TransactionStatus.choices()) transaction_type = models.CharField(max_length=255, choices=TransactionType.choices()) #enums.py class TransactionType(Enum): IN = "IN", OUT = "OUT" @classmethod def choices(cls): print(tuple((i.name, i.value) for i in cls)) return tuple((i.name, i.value) for i in cls) class TransactionStatus(Enum): INITIATED = "INITIATED", PENDING = "PENDING", COMPLETED = "COMPLETED", FAILED = "FAILED" ERROR = "ERROR" @classmethod def choices(cls): print(tuple((i.name, i.value) for i in cls)) return tuple((i.name, i.value) for i in cls)
However, when I am trying to access this model through admin I am getting the following error :
Django Version: 1.11 Exception Type: ValueError Exception Value: too many values to unpack (expected 2)
I followed two articles that described how to use enums:
- https://hackernoon.com/using-enum-as-model-field-choice-in-django-92d8b97aaa63
- https://blog.richard.do/2014/02/18/how-to-use-enums-for-django-field-choices/
Answer
For Django 2.x and lower:
You define an Enum
by setting the various options as documented here:
class TransactionStatus(Enum): INITIATED = "INITIATED" PENDING = "PENDING" COMPLETED = "COMPLETED" FAILED = "FAILED" ERROR = "ERROR"
Note there are no commas! This allows you later in your code to refer to TransactionStatus.ERROR
or TransactionStatus.PENDING
.
The rest of your code is correct. You get the choices
by creating tuples of option.name
, option.value
.
UPDATE: For Django 3.x and higher, use the built-in types TextChoices
, IntegerChoices
and Choices
as described here. That way you don’t have to construct the choices
tuple yourself.