python - Django 枚举属性相等

标签 python django enums

我在 Django 模型中使用枚举,例如:

class AwesomeNess(Enum):
    slight = "SLIGHT"
    very = "VERY"

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    awesomeness = models.CharField(
        max_length=255,
        choices=[(tag.value, tag.name) for tag in AwesomeNess],
        default=AwesomeNess.slight
    )

当我使用 Django 的过滤器功能时,它工作正常,例如:

d = Choice.objects.filter(awesomeness=AwesomeNess.slight)

但是,如果我这样做了,它就不起作用了:

choice_obj = Choice.objects.get(id=1)
choice_obj.awesomeness == AwesomeNess.slight # will return False
choice_obj.awesomeness == "AwesomeNess.slight" # will return True

由于值存储为字符串,看起来 Django 在返回数据时忘记将它们转换回枚举。 这会在编码时造成不一致,因为 django 模型过滤器可以查询枚举,而属性相等性过滤要求我使用枚举的字符串表示。

编辑:枚举是从另一个模型类导入的,因此不能用 Django 的内置选择类替换它。

EDIT2:在我对此进行调查时,我还注意到以下内容:

myobj = Choice.objects.get(id=1)
myobj.awesomeness  # <<-- string type
myobj.awesomeness =  AwesomeNess.very <<-- object changes type to enum
myobj.save()
myobj2 = Choice.objects.get(id=1) <<-- upon reload from db, the updated value is returned as string

作为 Django 的新手,这对我来说似乎非常危险,并且在我读过的任何“如何在 Django 中使用枚举”文章中都没有提到。这仅仅是因为我使用的 Django 版本太旧了吗?

有解决办法吗?我做错了什么吗?指点不胜感激! 哦,顺便说一句:这是在 Django 2.2.24 上。也许以后的版本改进了对枚举的支持?

最佳答案

发生这种情况的原因是因为选项在给定的值上调用了 str,因此这意味着它会将 "AwesomeNess.slight" 存储为字符串(如果将其设置为默认值)。

, 你可以使用 TextChoices class [Django-doc]这与使用 Enum 完全相同。因此,您可以定义一个 TextChoices 模型:

class Choice(models.Model):

    class <strong>AwesomNess</strong>(models.TextChoices):
        SLIGHT = 'SLIGHT', 'slight'
        VERY = 'VERY', 'very'

    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    awesomeness = models.CharField(
        max_length=255,
        choices=AwesomeNess<strong>.choices</strong>,
        default=AwesomeNess.SLIGHT
    )

对于旧版本,您需要指定您使用AwesomeNess:

class AwesomeNess(Enum):
    slight = 'SLIGHT'
    very = 'VERY'

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    awesomeness = models.CharField(
        max_length=255,
        choices=[(tag.value, tag.name) for tag in AwesomeNess],
        default=<strong>AwesomeNess.slight.value</strong>
    )

关于python - Django 枚举属性相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69645324/

相关文章:

python - 有没有可能为动态语言创建编译器而不失去他的动态特性?

python - 如何在没有 QProcess 的情况下将终端嵌入到 PyQt5 应用程序中?

django - 从 ORM 加速数据库插入

c# - 将 switch 语句重构为 enum

python - 从 python 访问 API objc 常量和枚举

python - 如何使用 python 修改 XML 中的元素文本

python - 在python中合并n个排序的元组列表

python - 从我的 Django 应用程序中的数据库中选择数据

python - django 在更改时提交表单

sql - 我应该将枚举存储在数据库级别还是应用程序逻辑 (.NET) 中?