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:
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