在Django中,我正在try 创建一个基于枚举的数据库字段.我正在避免使用外部库,并且只想使用普通的Django4.

本质上,我是在复制Python - Covert enum to Django models.CharField choices tuple中给出的例子

但是,枚举值不会强制执行.我可以很容易地创建一个包含animal = 'foo'的数据库条目,它会很高兴地将其写入数据库.

我预计这会产生一个IntegrityError,因为我显式地使用了一个枚举,所以只有有效的值才会在db中结束.

推荐答案

Django确实没有强制枚举值,或者至少不是现成的.严格地说,这could件事是可以完成的:它将 Select 权交给了移民.但迁移系统不会创建特定类型,或者至少在默认情况下不会创建.

但是,您可以使用CheckConstraint [Django-doc]来强制执行这些操作:

from django.db.models import Q


class AnimalModel(models.Model):
    class Animal(models.TextChoices):
        DOG = 'dog'
        CAT = 'cat'

    animal = models.CharField(choices=Animal.choices)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(animal__in=list(Animal)), name='animal_valid'
            )
        ]

话虽如此,通常您会通过表单、序列化程序等来处理数据,以验证这一点.通常,仅仅通过模型输入数据是一个好主意:Django的模型默认情况下出于性能原因跳过了很多验证.

Django相关问答推荐

无法将关键字average_rating解析为字段

Django rest framework, AttributeError: 'str' object has no attribute 'data' 无法使用表单上传图片

Django 仅预取相关模型的最新对象

AttributeError:模块rest_framework.serializers在 Swagger 中的 Django 中没有属性NullBooleanField

如何将 select_related 应用于 Django 中的 m2m 关系的对象?

基于每个条目的 Django Queryset 过滤

Django 应用程序似乎无法识别相关名称?

Django中的 联合(Union) 和相交(Intersect)

django-rest-framework 如何使模型序列化器字段成为必需

根据模型属性获取django对象id

如何在 django 中处理这种竞争条件?

Django 管理命令参数

Python 和 Django OperationalError (2006, 'MySQL server has gone away')

Django App 配置不当 - 应用程序模块有多个文件系统位置

如何在 Django 测试框架中修改会话

django excel xlwt

从 virtualenv 中,pip freeze > requirements.txt 给出了一堆垃圾!如何修剪它?

在 Django 中舍入小数点

在 Django 1.8 或更高版本中填充时出现Models aren't loaded yet"错误

模拟 Django 查询集以测试采用查询集的函数