Django模型选择在选择无效值时未引发错误

14

我在Django中有一个包含选择字段的对象

class CustomFieldType(models.Model):
    STRING = 'STRING'
    DATE = 'DATE'
    BOOLEAN = 'BOOLEAN'
    NUMERIC = 'NUMERIC'
    EMAIL = 'EMAIL'
    TYPE_CHOICES = (
        (STRING, _('String')),
        (DATE, _('Date')),
        (BOOLEAN, _('Boolean')),
        (NUMERIC, _('Numeric')),
        (EMAIL, _('Email'))
    )
    name = models.CharField(max_length=256)
    field_type = models.CharField(choices=TYPE_CHOICES, default=STRING, max_length=10)
    company = models.ForeignKey('Company')

    class Meta:
        unique_together = ('name', 'company')

    def __unicode__(self):
        return self.name

在我的Django控制台中

$> CustomFieldType.objects.create(name='custom_name',field_type='noError',company=mycompany)
<CustomFieldType: custom_name>
$> CustomFieldType.objects.get(name='custom_name').field_type
u'noError'

为什么Django没有引发错误(ValidationError)?还是我漏掉了什么?

3个回答

12

choices 选项仅用于预填充表单下拉字段; 它不强制执行任何验证:

如果提供此选项,则默认的表单小部件将是一个选择框,其中包含这些选择,而不是标准文本字段。


2
有没有办法强制执行验证? - user1631075
2
@user1631075 数据库永远不应该进行任何验证。所有验证都应在数据输入数据库之前进行。如果您期望数据库进行验证,则您的设计存在问题。 - Diemuzi
9
@Diemuzi,那是不正确的,或者我们对“验证”这个词有不同的理解。我的意思是,如果数据库没有进行任何验证,那么设置最大长度、整数字段、字符字段、布尔字段等有什么意义呢?数据库应该是唯一的真相来源。宇宙永恒的定律之一是数据比应用程序更寿命长。这就是为什么随着时间的推移,Django会增加越来越多支持构建数据库级约束的功能。https://docs.djangoproject.com/en/dev/ref/models/constraints/#module-django.db.models.constraints - Dustin Wyatt
1
如果提供了选项,它们将通过模型验证进行强制执行。请参见其他答案。 - djvg
我们是否使用了不同的Django版本?因为在我的版本中,验证是强制执行的。给定的值必须在给定的选项中。 - LearnToday

4

更新

自django 2.1版本以来,设置choices将会引发验证错误:

如果提供了选项,它们将被模型验证强制执行,并且默认的表单小部件将是一个具有这些选项的下拉框,而不是标准的文本字段。

请注意,CustomFieldType.objects.create并不足够。您需要执行类似于model_instance.full_clean()的操作来引发错误。就像模型验证文档中所述一样。


0

我遇到了同样的问题,我使用save()方法而不是create()方法解决了它,你必须在执行save()之前使用full_clean(),像这样:

x = "your model name"()
x."field" = "value"
.
.
.
"your model name".full_clean(self = x)
"your model name".save(self = x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接