在 Django 中将模型字段设置为必填
Posted
技术标签:
【中文标题】在 Django 中将模型字段设置为必填【英文标题】:Set Model Field as Required in Django 【发布时间】:2020-10-09 04:10:40 【问题描述】:Django 不会在模型/数据库级别强制执行 NOT NULL。 device_serial 既不应该有空白 '' 也不应该为空
class Device(models.Model):
device_serial = models.CharField(max_length=36, unique=True, null=False, blank=False)
....etc
下面的语句完全正常!我预计它会失败,因为 device_serial 是必需的。它不应该接受空字符串 ''
Device.objects.create(device_serial='')
如何在模型/数据库级别设置必填字段?我可能在这里做错了什么?我不明白我哪里出错了。我尝试了 ''.strp() 将空字符串转换为 None 但它不起作用
【问题讨论】:
空字符串不为NULL,尝试传递None 【参考方案1】:就数据库而言,它只允许由null=True/False
处理的null/not null,默认为False
。 blank=True/False
仅用于管理页面。
字符串''
不被认为是空的,这就是当你有null=False
约束时它被数据库接受的原因。
如果您想避免在数据库级别出现空字符串,您可以在模型本身上覆盖 save()
,并在 device_serial
设置为空字符串时引发异常,例如:
from django.core.exceptions import ValidationError
class Device(models.Model):
device_serial = models.CharField(max_length=36, unique=True)
def save(self, *args, **kwargs):
if self.device_serial == '':
raise ValidationError('device_serial cannot be empty')
super().save(*args, **kwargs)
现在,当您尝试使用空字符串创建对象(调用save()
)时,将引发以下异常:
django.core.exceptions.ValidationError: ['device_serial cannot be empty']
【讨论】:
谢谢。您的解决方案有效,但我找到了解决方法。设置 default=None 会强制空字符串为 null,这会使 create() 失败.... device_serial = models.CharField(max_length=36, unique=True, default=None) 很高兴!,我不认为设置default=None
会强制空字符串为空。您确定您没有覆盖save()
并且没有使用空字符串device_serial
保存的对象吗?因为unique=True
约束会引发异常
我的错!正确的。我对 Device.objects.create(device_serial=None) 进行了硬编码,却忘了把它拿出来。它没有用。回到你的解决方案'【参考方案2】:
莫哈末的回答奏效了!或者,数据库级别的检查约束也可以。
class Meta:
constraints = [
models.CheckConstraint(check=~models.Q(device_serial=''), name='chk_device_device_serial')
]
【讨论】:
这是最可靠的答案。它在数据库级别强制执行约束,因此它适用于未调用save()
的情况(例如,使用 bulk_update 时)。 constraints
特性是在 Django 2.2 中添加的。对于旧版本,您可以在手工迁移中使用原始 sql 添加数据库约束。
博文更多信息Django’s Field Choices Don’t Constrain Your Data以上是关于在 Django 中将模型字段设置为必填的主要内容,如果未能解决你的问题,请参考以下文章