使用 null=False 保存空字段时不会引发异常 - Django

No exception raised when saving an empty field with null=False - Django

我有以下型号:

class User(models.Model):
    email = models.EmailField(max_length=254, null=False, unique=True)
    referral_code = models.CharField(max_length=10, null=False, unique=True)

并使用 Django shell 保存一个 referral_code 未定义的用户实例:

u = User(email="test@example.com")
u.save()

这没有引发异常。我的理解是 null=False 需要设置 referral_code - 不是这样吗?我将如何实现这种行为?

更新

我注意到该字段设置为 u.referral_code='',因此考虑到唯一性约束,这在我尝试使用新实例重复该过程时引发了异常。我宁愿抛出异常,因为我没有设置字段...

您的 referral_code 的值不是 null,而是 ''(空字符串)。这是 CharField.

的默认值

与问题一起更新:

您可以在数据存储到数据库之前通过覆盖模型save引发错误

class User(models.Model):
    email = models.EmailField(max_length=254, null=False, unique=True)
    referral_code = models.CharField(max_length=10, null=False, unique=True)

    def save(self, *args, **kwargs):
        assert self.email, "The 'email' field must be populated."
        super().save(*args, **kwargs)

应该注意的是,在可能的情况下,这并不优于表单验证。


现在更新 Django 的新功能可用:

Django's Constraints 允许您添加自定义数据库约束:

class User(models.Model):
    email = models.EmailField(max_length=254, null=False, unique=True)
    referral_code = models.CharField(max_length=10, null=False, unique=True)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=(~models.Q(referral_code='')),
                name='referral_code_populated',
            )
        ]