强制进行Django查询的INNER JOIN

jar*_*oal 4 python sql django orm

这是我的架构:

城市 - >摄影师

我正在尝试获得至少有一位摄影师的城市名单,并返回城市的摄影师数量.

这是我正在使用的查询集:

City.objects.annotate(photographer_count=aggregates.Count('photographers')).filter(photographer_count__gt=0).order_by('-photographer_count')
Run Code Online (Sandbox Code Playgroud)

这完全符合我的预期,除了Django选择在城市/摄影师与左外连接之间进行连接的某些原因.如果我抓取SQL文本并简单地将"left outer"更改为"inner",则查询从~11秒变为200ms,结果相同.

我已经尝试在注释前面添加一个过滤器来暗示Django它应该是内部连接,但这不起作用.

任何Django查询巫毒我可以执行此操作以获得内部联接?我意识到我可以使用直接SQL,但更愿意通过ORM.

Ant*_*ker 9

默认情况下,LEFT JOIN生成a以便Django甚至可以为没有摄影师的城市提供行.如果你知道你不想要那些,那么强制Django生成一个INNER JOIN:

City.objects.filter(
    photographer__isnull=False
).annotate(
    photographer_count=aggregates.Count('photographers')
).filter(
    photographer_count__gt=0
).order_by(
    '-photographer_count'
)
Run Code Online (Sandbox Code Playgroud)

具体来说,第一个过滤器告诉Django一个INNER JOIN是安全的.它必须在annotate()通话之前到来.