["python","django","python-3.x","django-models","enums"]
How can one use enums as a choice field in a Django model?

I have a model class in which I want two fields to be choice fields, so to populate those choices I am using an enum as listed below: #models.py class Transaction(models.Model): transaction_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 the Django 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/
django > 3.0 - have built-in support for Enums from django.utils.translation import gettext_lazy as _ class Student(models.Model): class YearInSchool(models.TextChoices): FRESHMAN = "FR", _("Freshman") SOPHOMORE = "SO", _("Sophomore") JUNIOR = "JR", _("Junior") SENIOR = "SR", _("Senior") GRADUATE = "GR", _("Graduate") year_in_school = models.CharField( max_length=2, choices=YearInSchool.choices, default=YearInSchool.FRESHMAN, ) def is_upperclass(self): return self.year_in_school in { self.YearInSchool.JUNIOR, self.YearInSchool.SENIOR, } Problem in your code is that INITIATED = "INITIATED", a comma after INITIATED option and other options. when we add comma after any string it will become a tuple. See an example below s = 'my str' print(type(s)) # output: str s = 'my str', print(type(s)) # output: tuple #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.value, i.name) for i in cls)) return tuple((i.value, i.name) for i in cls) For django > 3.0 https://docs.djangoproject.com/en/4.0/ref/models/fields/#field-choices-enum-types