Django CheckConstraint:反向ForeignKey查找的元素不能为空
Posted
技术标签:
【中文标题】Django CheckConstraint:反向ForeignKey查找的元素不能为空【英文标题】:Django CheckConstraint: Elements of reverse ForeignKey lookup must not be empty 【发布时间】:2020-05-27 03:35:23 【问题描述】:我有这些模型:
class Container(models.Model):
...
class Meta:
constraints = [
models.CheckConstraint(
check=~Q(elements=None),
name='container_must_have_elements'
),
]
class Element(models.Model):
container = models.ForeignKey(Container),
related_name='elements',
on_delete=models.CASCADE
)
我想强制每个Container
对象必须至少有一个Element
通过外键关系引用它。
如您所见,我已经添加了一个检查约束。但是,Q
对象上的否定运算符 ~
似乎是被禁止的。当我尝试应用生成的迁移时,我得到了django.db.utils.NotSupportedError: cannot use subquery in check constraint
。
没有否定运算符,约束似乎是有效的(它只是由于数据完整性错误而失败)。
是否有另一种方式可以表达此约束以使其受到CheckConstraint
的支持?
(例如,有没有办法检查elements
的集合是否不为空?)
【问题讨论】:
请注意,此约束将产生一种循环依赖,因为您无法在没有元素的情况下创建Container
,但要创建Element
,您需要一个容器来引用。在我看来,有这个约束是没有意义的
是的,你是对的,但仍然可以满足约束:两个模型的对象必须在单个数据库事务中创建。
@PeterF 我不太确定这单笔交易。 Container仍然需要先插入db才能获得pk,然后才能插入Element。那么第一次插入不会引发错误,即您确定仅在事务结束时检查约束吗?
立即或仅在事务提交后强制执行约束都是可配置的:postgresql.org/docs/9.1/sql-set-constraints.html
以下是使用 SQL 的方法:***.com/questions/3880698/… 他们需要在 SQL 中定义一个函数。似乎仅使用 python 代码无法对其他表定义约束。
【参考方案1】:
我将通过总结问题的 cmets 来回答我自己的问题。
检查约束旨在检查表中的每一行是否存在条件,该条件仅考虑行本身,而不会为此连接其他表。
坚持使用 SQL,可以通过在 SQL 中定义一个函数并从约束中调用它来制定包括其他表的扩展约束。
Django 2.2 中引入的CheckConstraint
仅通过使用Q
对象支持表本身的条件。
development version of the documentation 表示除了Q
对象之外,还将支持布尔Expression
s。
这在 Django 3.0 中尚不可用,但在未来的版本中。
【讨论】:
以上是关于Django CheckConstraint:反向ForeignKey查找的元素不能为空的主要内容,如果未能解决你的问题,请参考以下文章