首页 > 解决方案 > Django CheckConstraint:反向 ForeignKey 查找的元素不能为空

问题描述

我有这些模型:

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是否不为空?)

标签: djangodjango-modelsdjango-ormcheck-constraintsdjango-q

解决方案


我将通过总结问题的评论来回答我自己的问题。

检查约束旨在检查表中的每一行是否存在条件,该条件仅考虑行本身,而不会为此连接其他表。

坚持使用 SQL,可以通过在 SQL 中定义一个函数并从约束中调用它来制定包括其他表的扩展约束。

Django 2.2中CheckConstraint引入的 仅支持使用Q对象对表本身的条件。文档的开发版本表明,除了Q对象之外,还将支持 boolean Expressions。这在 Django 3.0 中尚不可用,但在将来的版本中可用。


推荐阅读