如何在 Django 中实现广义唯一性 DB 约束 (A,B) 和 (B,A)?
Posted
技术标签:
【中文标题】如何在 Django 中实现广义唯一性 DB 约束 (A,B) 和 (B,A)?【英文标题】:How to implement a generalized uniqueness DB constraint (A,B) and (B,A) in Django? 【发布时间】:2021-11-12 17:36:36 【问题描述】:我想在使用字段 one='a' 和 two='b' 创建对象之前检查数据库,如果数据库已经有字段 one='b' 和两个='a'(相反的顺序)。即保证(一,二)和(二,一)中只有一个存在。这就像一个广义的唯一性约束。
我正在使用 Django 3.2。
我看到CheckConstraint 支持布尔值Expression,一种类型的表达式是聚合。所以我可以想象测试 (one, two) 和 (two, one) 的行数最多为 1。但是,这听起来很昂贵,而且我也没有看到如何在 CheckConstraint 中使用 Count 的示例.
或者,我可以实现一个发出查询的pre_save 信号。这似乎更好,因为我手头有数据来形成查询。但是,我看不到如何使用 pre_save 信号来防止保存。 它有我可以使用的返回值吗?我在文档中没有看到。
编辑:第三种选择可能是覆盖save
来进行检查。
我也对其他想法持开放态度。
【问题讨论】:
这能回答你的问题吗? Django unique together constraint in two directions 确实是同一个问题,但没有回答。在那里的评论中:“在某些未来版本中,UniqueConstraints(Django 文档)将支持表达式,因此您可以编写一些表达式,将两个字段与一些分隔符并以某种顺序连接起来,从而有效地实现您想要的。”好吧,UniqueConstraints 支持表达式,但我不明白如何使用它们来解决这个问题。这实际上是我上面的问题。 唯一约束还不支持expressions...这是 Django 4.0 的一部分,预计将于 2021 年 12 月发布。(注意:该问题中的评论是我写的:p) 哦,我搞糊涂了。支持表达式的是 CheckConstraint-s。谢谢你的信息。那我先关了。 【参考方案1】:我想不出任何允许这种类型约束的数据库级约束。
因此可以在应用程序级别实施约束。您是否在提交表单时创建模型?在这种情况下,您可以在表单验证代码中检查数据库中的现有行。
【讨论】:
谢谢,我更愿意在模型级别而不是表单级别进行检查。也许我可能会覆盖save
。以上是关于如何在 Django 中实现广义唯一性 DB 约束 (A,B) 和 (B,A)?的主要内容,如果未能解决你的问题,请参考以下文章
django.db.utils.IntegrityError:唯一约束失败:rango_category__new.slug
Django 导入 - 导出:尝试在具有唯一性或唯一性约束的字段中插入重复记录时出现 IntegrittyError
django.db.utils.IntegrityError:重复键值违反唯一约束“django_content_type_pkey”
django.db.utils.IntegrityError:重复键值违反唯一约束“auth_permission_pkey”