Django:如何在distinct()之后过滤()

Jac*_*ack 8 django

如果我们在调用distinct()之后将调用链接到filter(),则在distinct之前将过滤器应用于查询.应用distinct 如何过滤查询结果?

Example.objects.order_by('a','foreignkey__b').distinct('a').filter(foreignkey__b='something')

由filter()生成的SQL中的where子句表示过滤器在distinct之前应用于查询.我想过滤不同的查询集.

这可能很简单,但我无法弄明白,我找不到任何东西.

编辑1:

我需要在ORM中做到这一点......

SELECT z.column1, z.column2, z.column3 FROM ( SELECT DISTINCT ON (b.column1, b.column2) b.column1, b.column2, c.column3 FROM table1 a INNER JOIN table2 b ON ( a.id = b.id ) INNER JOIN table3 c ON ( b.id = c.id) ORDER BY b.column1 ASC, b.column2 ASC, c.column4 DESC ) z WHERE z.column3 = 'Something';

(顺便说一句,我正在使用Postgres.)所以我想我要问的是"你如何在ORM中嵌套子查询?这可能吗?" 我会查看文档.

对不起,如果我之前没有具体.我脑子里还不清楚.

Kei*_*ley 6

这是一个老问题,但在使用Postgres时,您可以执行以下操作以强制对"Distinct"行进行嵌套查询:

foo = Example.objects.order_by('a','foreign_key__timefield').distinct('a')
bar = Example.objects.filter(pk__in=foo).filter(some_field=condition)
Run Code Online (Sandbox Code Playgroud)

bar是OP中请求的嵌套查询,无需求助于raw/extra等.经测试在1.10中工作但文档建议它应该至少恢复到1.7.

我的用例是过滤反向关系.如果Example有一些ForeignKey来模拟Toast,那么你可以这样做:

Toast.objects.filter(pk__in=bar.values_list('foreign_key',flat=true))
Run Code Online (Sandbox Code Playgroud)

这将为您提供Toast的所有实例,其中最新的关联示例符合您的过滤条件.

关于性能的大健康警告,使用这个如果bar可能是一个巨大的查询集,你可能会有一个糟糕的时间.


Jac*_*ack 2

非常感谢大家的帮助。我尝试了这两种建议,但都无法使这些建议发挥作用,但我认为它让我朝着正确的方向前进。

我最终使用了

from django.db.models import Max, F

Example.objects.annotate(latest=Max('foreignkey__timefield')).filter(foreignkey__timefield=F('latest'), foreign__a='Something')
Run Code Online (Sandbox Code Playgroud)

这会检查每个示例的最新foreignkey__timefield是什么,如果它是最新的并且a=something则保留它。如果它不是最新的或者每个示例的 a!=something ,那么它就会被过滤掉。

这不会嵌套子查询,但它给出了我正在寻找的输出 - 而且它相当简单。如果有更简单的方法我真的很想知道。