我有一个模型类,我希望其中的两个字段成为一个选择字段,因此为了填充这些选择,我正在使用下面列出的枚举
#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)
但是,当我尝试通过管理员访问此模型时,出现以下错误:
Django Version: 1.11
Exception Type: ValueError
Exception Value:
too many values to unpack (expected 2)
我关注了两篇描述如何使用枚举的文章:
最佳答案
Django 3.0 内置了对枚举的支持
例子:
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, )
These work similar to enum from Python’s standard library, but with some modifications:
- Enum member values are a tuple of arguments to use when constructing the concrete data type. Django supports adding an extra string value to the end of this tuple to be used as the human-readable name, or
label
. Thelabel
can be a lazy translatable string. Thus, in most cases, the member value will be a(value, label)
two-tuple. If a tuple is not provided, or the last item is not a (lazy) string, the label is automatically generated from the member name.- A
.label
property is added on values, to return the human-readable name. A number of custom properties are added to the enumeration classes –.choices
,.labels
,.values
, and.names
– to make it easier to access lists of those separate parts of the enumeration. Use.choices
as a suitable value to pass to choices in a field definition.- The use of
enum.unique()
is enforced to ensure that values cannot be defined multiple times. This is unlikely to be expected in choices for a field.
欲了解更多信息,check the documentation
注意事项:
正如@Danielle Madeley 指出的那样,如果您尝试直接访问 year_in_school
属性,Django 仍然返回原始字符串而不是 Enum 对象:
>>> student.year_in_school
'FR'
我通常做的是创建一个返回 Enum 对象的辅助方法:
class Student(models.Model):
...
def get_year_in_school(self) -> YearInSchool:
# Get value from choices enum
return self.YearInSchool[self.year_in_school]
关于python - 如何在 Django 模型中使用枚举作为选择字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54802616/