为什么我可以在不定义所有非null字段的情况下保存Django模型实例

时间:2019-06-04 09:51:01

标签: django postgresql

当我在Django中定义一个不可为空的字段时,它允许我保存模型实例,而无需为此不可为空的字段指定任何值。这不是我所期望的。我该如何强制产生错误?

Postgres 9.1 Django 2.1 视窗 python 3.6

from django.db import models
class Wwtp(models.Model):
    name = models.CharField(max_length=100, null=False,
                            blank=False, unique=True)
    short_name = models.CharField(
        max_length=10, null=False, blank=False, unique=True)

如预期的那样,不允许我使用明确的空short_name保存它。

mdl.Wwtp.objects.create(name='Wwtp4', short_name=None)

但是我可以在不指定short_name的情况下保存Wwtp实例:

mdl.Wwtp.objects.create(name='Wwtp4')

当我尝试时:

mdl.Wwtp.objects.create()

它给了我

django.db.utils.IntegrityError: duplicate key value violates unique constraint "api_wwtp_short_name_key"
DETAIL:  Key (short_name)=() already exists.

显然django在short_name的数据库中填充了一个空值,但是不允许这样做……我如何强制数据库不允许这样做?

1 个答案:

答案 0 :(得分:1)

您不能使用CharField。空值是空字符串'',而不是NULL。您已经设置了blank=False,因此,如果在保存它们之前 clean 您的模型或模型表单,您会发现的。但是它不能在数据库级别强制执行。

请注意,blank=False, null=False是默认设置,因此您实际上不必指定它。

此外,如果您真的只想支持PostgreSQL,则可以使用RunSQL进行自定义迁移,以在表上创建列,并手动添加添加约束所需的SQL(例如,使用{{1} }。请参见here,以了解如何确保Django也知道该列已创建,并且不尝试在下一次迁移中添加它。有一个example here

[编辑]在Django 2.2中,您可以在模型的CHECKconstraints属性中添加一个CheckConstraint

Meta