ChatGPT解决这个技术问题 Extra ChatGPT

如何找到两个 Django 查询集的联合?

我有一个带有两个自定义管理器方法的 Django 模型。每个都根据对象的不同属性返回模型对象的不同子集。

有没有办法获得一个查询集,或者只是一个对象列表,这是每个管理器方法返回的查询集的联合?

(来自已删除的答案)有关适用于不同模型的 QuerySet 的变体,请参阅此问题:stackoverflow.com/questions/431628/…
从 1.11 版本开始,django 查询集有一个内置的 union 方法。我已将其添加为将来参考的答案

F
Flimm

这有效,看起来更干净:

records = query1 | query2

如果您不想重复,则需要附加 .distinct()

records = (query1 | query2).distinct()

虽然接受的答案返回一个可迭代的联合(确切地说是列表),但正如 OP 所要求的那样,此方法返回一个真正的查询集联合。可以进一步操作此查询集,这在许多情况下都是需要的。
由于 Django 错误,此构造在处理 ManyToManyField 时有时会返回不正确的结果。例如,您有时会看到 records.count() 会大于 query1.count() + query2.count(),这显然是不正确的。
@Jian 你能用错误和 djangoproject 问题的链接澄清 django 版本吗?
记录 = 查询 1 |查询2; records = records.distinct() 会给我正确的结果
您可以在 Python 中重载运算符。请参阅docs.python.org/2/library/operator.html。所以 Django 所做的就是为 QuerySet 对象创建特殊的方法。请参阅此处的代码:github.com/django/django/blob/master/django/db/models/… QuerySet 类为 __and____or__ 提供了在两个 QuerySet 对象之间使用 &| 运算符时调用的方法(也用于 { 9} 类)。
j
jidicula

version 1.11 开始,django 查询集有一个内置的联合方法。

q = q1.union(q2) #q will contain all unique records of q1 + q2
q = q1.union(q2, all=True) #q will contain all records of q1 + q2 including duplicates
q = q1.union(q2,q3) # more than 2 queryset union

有关更多示例,请参阅我的 blog post


我无法让 all=True 工作。最终将我的查询集转换为一组,然后再将其返回给客户端。
@BradenHolt,all=True,表示它将包含重复记录。您可以简单地删除 all=True 以避免将其转换为集合。
在这不起作用 DjangoFilterBackend 之后,我如何使用 union 和 DjangoFilterBackend ?
不幸的是,这似乎不适用于在模型的 Meta 中定义了默认排序的模型。每当我尝试将这些与 .union 组合时,我都会收到以下错误:“复合语句的子查询中不允许使用 ORDER BY。”
X
Xianxing

我建议使用 'query1.union(query2)' 而不是 'query1 |查询2';我从上述两种方法得到了不同的结果,前一种是我所期望的。以下是我遇到的情况:

print "union result:"
for element in query_set1.union(query_set2):
    print element

print "| result:"
for element in (query_set1 | query_set2):
    print element

结果:

union result:
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object

| result:
KafkaTopic object
KafkaTopic object