【问题标题】:Using integers and strings together in Django choice field在 Django 选择字段中一起使用整数和字符串
【发布时间】:2021-09-09 17:44:17
【问题描述】:

我正在尝试将最新 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:“int”和“States”的实例之间不支持“>”

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

【问题讨论】:

  • 检查 my answer here 以了解将类常量添加到 Enum 的方法。

标签: python django enums modelchoicefield django-model-field


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2014-04-04
    • 2023-02-26
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多