Django - 使用 Q 跨越空关系的查询集

Posted

技术标签:

【中文标题】Django - 使用 Q 跨越空关系的查询集【英文标题】:Django - Queryset spanning null relationships using Q 【发布时间】:2010-11-09 18:56:43 【问题描述】:

考虑模型:

#Models
class A(models.Model):
    fieldOfA = models.CharField(max_length = 4)
class B(models.Model):
    fieldOfB = models.CharField(max_length = 4)
class C(models.Model):
    classA = models.ForeignKey(A, blank=True, null=True)
    classB = models.ForeignKey(B, blank=True, null=True)

当我创建 C 的对象时,我确保对象具有 classA 或 classB 关系。

我正在寻找一个单一的查询集,它为我获取特定 fieldOfA 或特定 fieldOfB 值的 C 对象。

我试过了,但它失败了(返回 [],尽管结果有效)。

#Views - assume double underscore in the query
from django.db.models import Q
my_query = C.objects.filter(Q(classA _ _isnull = False, classA _ _fieldOfA = 'foo') | Q(classB _ _isnull = False, classB _ _fieldOfB = 'foo'))

我看到的问题是“|”那是应用。 classA 和 classB 的两个不同查询集工作正常。有什么办法可以应用单个查询集来完成这项工作?或者更糟糕的是,一种合并单个查询集的方法。

【问题讨论】:

【参考方案1】:

如果您可以确定一个 C 有一个 A 或一个 B,但绝不会两者兼有,那么您的 isnull 约束是多余的。如果运行以下命令会发生什么?

C.objects.filter(Q(classA__fieldOfA = 'foo') | Q(classB__fieldOfB = 'foo'))

如果还是不行,运行manage.py shell并在运行上面的查询之后(确保settings.DEBUGTrue,检查上面生成的SQL

>>> from django.db import connection
>>> connection.queries()

你看到了什么?

【讨论】:

不幸的是,消除冗余并没有帮助。 SQL 对两个 Q 都有两个“左外连接”(内部后跟一个内连接)。第二个 Q 不应该有一个 RIGHT OUTER JOIN 吗? fieldB 值未恢复。不过感谢您的帮助。我现在正在链接(以某种方式合并)这两个查询集,这也适用于我。使用此代码 sn-p - djangosnippets.org/snippets/1103【参考方案2】:

实际上,您可以以相同的方式组合QuerySets。像这样:

C.objects.filter(classA__fieldOfA='foo') | C.objects.filter(classB__fieldOfB='foo')

【讨论】:

以上是关于Django - 使用 Q 跨越空关系的查询集的主要内容,如果未能解决你的问题,请参考以下文章

按外键/相关字段分组 django 查询集

Django - 返回 Post 对象查询在本地时间跨越到前端的月份列表

跨越鸿沟——图数据库查询语言的八个先决条件——上篇

跨越分区的SparkSQL DataFrame顺序

如何在表格中跨越单元格后修复空边框线?

Django Newbie - 使用多字段表单,如何消除查询集中的空字段