1

我正在尝试将最新 Django 版本中的新 Enum 类型用于选择字段。具体来说,我试图将美国的各个州存储如下:

class States(models.TextChoices):
    ALABAMA = 'AL', 'Alabama'
    ALASKA = 'AK', 'Alaska'
    .....
    .....
    WISCONSIN = 'WI', 'Wisconsin'
    WYOMING = 'WY', 'Wyoming'


class PersonalInfo(models.Model):
    state = models.CharField(max_length=2, choices=States.choices, default=States.ALABAMA)

按预期工作。现在,我还尝试使 max_length 变量也成为选择类的类属性,以通过执行以下操作使代码更加模块化:

class States(models.TextChoices):
    ALABAMA = 'AL', 'Alabama'
    ALASKA = 'AK', 'Alaska'
    .....
    .....
    WISCONSIN = 'WI', 'Wisconsin'
    WYOMING = 'WY', 'Wyoming'
    MAX_LENGTH = 2
    

class PersonalInfo(models.Model):
    state = models.CharField(max_length=States.MAX_LENGTH, choices=States.choices, default=States.ALABAMA)

这给了我一个错误如下:

如果 self.max_length 不是 None 并且 choice_max_length > self.max_length:
TypeError: '>' not supported between 'int' and 'States'

我知道 Django 还为整数提供了一个替代的 IntegerChoices,但是我如何同时使用文本和整数选择。

4

1 回答 1

2

TextChoices必须包含字符串值,它们的工作方式是枚举您在类中定义的内容。所以你有混合类型,这些类型不起作用,因为它会尝试将其包含2为选项之一,因为它是选项类的一部分。

您可以做的是将选择定义为一个有点像这样的常量;

    STATE_MAX_LENGTH = 2


    class States(models.TextChoices):
        ALABAMA = 'AL', 'Alabama'
        ALASKA = 'AK', 'Alaska'
        .....
        .....
        WISCONSIN = 'WI', 'Wisconsin'
        WYOMING = 'WY', 'Wyoming'
        

    class PersonalInfo(models.Model):
        state = models.CharField(max_length=STATE_MAX_LENGTH, choices=States.choices, default=States.ALABAMA)

为了确认,这里是来自 django 的选择类;

class Choices(enum.Enum, metaclass=ChoicesMeta):
    """Class for creating enumerated choices."""

    def __str__(self):
        """
        Use value when cast to str, so that Choices set as model instance
        attributes are rendered as expected in templates and similar contexts.
        """
        return str(self.value)


class IntegerChoices(int, Choices):
    """Class for creating enumerated integer choices."""
    pass


class TextChoices(str, Choices):
    """Class for creating enumerated string choices."""

    def _generate_next_value_(name, start, count, last_values):
        return name
于 2021-06-26T21:15:31.023 回答