添加 Django 的 Q() 对象并获得两个独占的 JOIN ON。



那么这就是场景:

class Person(models.Model):
    ...
class Aktion(models.Model):
    ...
class Aktionsteilnahme(models.Model):
    person = models.ForeignKey(Person)
    aktion = models.ForeignKey(Aktion)

现在的问题是,我正在基于Q() -对象动态构建相当复杂的查询。它们的结尾是这样的:

Person.objects.filter(
    Q((Q()|Q(aktionsteilnahme__aktion=302))&
    (Q()|Q(aktionsteilnahme__aktion=547)))
)

可以(并且会自动)简化为:

Person.objects.filter(
    Q(aktionsteilnahme__aktion=302)&
    Q(aktionsteilnahme__aktion=547)
)
问题现在是,这会导致这样的SQL:
SELECT * FROM person
LEFT OUTER JOIN aktionsteilnahme ON ( person.id = aktionsteilnahme.person_id )
WHERE (aktionsteilnahme.aktion = 2890 AND aktionsteilnahme.aktion = 5924)

我实际需要的是:

Person.objects.filter(Q(aktionsteilnahme__aktion=302))
    .filter(Q(aktionsteilnahme__aktion=547))

生成我实际需要的内容:

SELECT * FROM person
INNER JOIN aktionsteilnahme ON ( person.id = aktionsteilnahme.person_id )
INNER JOIN aktionsteilnahme T4 ON ( person.id = T4.person_id )
WHERE (aktionsteilnahme.aktion = 302 AND T4.aktion = 547)

我不能使用提议的解决方案,因为所有这些都将再次被OR 'ed。

我必须能够做这样的事情:

Person.objects.filter(
    Q(
      Q(aktionsteilnahme__aktion=302))
      .filter(Q(aktionsteilnahme__aktion=547))
    )
    |
    Q(other_q_filters)
)

在摆弄了一些之后,我意识到:Django QuerySets可以被OR 'ed。

因此,我现在的解决方案是创建如下内容:
Person.objects.filter(Q(aktionsteilnahme__aktion=302))
      .filter(Q(aktionsteilnahme__aktion=547))
|
Person.objects.filter(Q(other_q_filters))

所有内部的AND s现在使用过滤器连接,最外面的OR s直接在QuerySets上是布尔|

小心!请求得到要慢得多由于内部子查询总是完全求值(不再"限制20")
OR -使用QuerySets将产生多个条目-所以最后一个

(QuerySet | QuerySet | QuerySet).distinct()

相关内容

  • 没有找到相关文章

最新更新