我有一个模型,其中有一个不可为空的CharField
和两个可为空的CharField
:
class MyModel(models.Model):
name = models.CharField('Name', max_length=255, null=False)
title = models.CharField('Title', max_length=255, blank=True)
position = models.CharField('Position', max_length=255, blank=True)
我想确保name
、title
和position
在一起是唯一的,因此使用UniqueConstraint
:
def Meta:
constraints = [
models.UniqueConstraint(
fields=['name', 'title', 'position'],
name="unique_name_title_position"
),
]
但是,如果title
是None
,则此约束不成立。
究其原因,这是因为您可以使用UNIQUE
约束将NULL
值插入到列中,因为NULL
不存在值,所以它永远不等于其他NULL
值,也不会被视为重复值,这意味着如果其中一个值为NULL
,则可能插入看起来重复的行。
在Django中严格执行这种独特性的正确方法是什么?
3条答案
按热度按时间2ledvvac1#
UniqueConstraint
不是在Django级别上强制执行的,而是直接在数据库上强制执行的。例如,PostgreSQL允许多个
Null
记录具有唯一性,而MSSQL不允许您可以检查列的每个子集是否为
CheckConstraint
,但您会发现这很繁琐,因为它要求每个组合都是唯一的indexed。为了避免这种混乱,你可以按照Django的
CharField
指南来做避免在基于字符串的字段(如CharField和TextField)上使用null。如果基于字符串的字段的null=True,则意味着它有两个可能的“无数据”值:NULL和空字符串。在大多数情况下,“无数据”有两个可能的值是多余的;“Django约定是使用空字符串,而不是NULL。一个例外是CharField同时设置了unique=True和blank=True。在这种情况下,需要null=True以避免在保存多个空值对象时违反唯一约束。
检查空字符串的唯一性
ckx4rj1h2#
当
title
是NULL
时,您只需要add one more constraint
这应保证
title
中NULL值的唯一性。您可以根据需要为NULL
值添加更多约束uemypmqf3#
你可以选择
title
和position
中从未出现过的值,并使用如下索引:这会将NULL值替换为其他值,从而防止重复。