class Zone(Model):
...
class Flight(Model):
zones = ManyToManyField(Zone)
flights = Flight.objects.filter(...)
qs1 = Zone.objects.annotate(
count=flights.filter(zones__pk=F('pk')).distinct().count(), # this is not valid expression
)
尽管在查询集中有F
且注释中有count()
,它仍然抛出错误TypeError: QuerySet.annotate() received non-expression(s): 0.
,这意味着该查询集已就地执行。
也不起作用,但是这次它只返回无效值(总是1,总是计数Zone单个对象而不是内部过滤器):
qs1 = Zone.objects.annotate(
count=Count('pk', filter=flights.filter(zones__pk=F('pk'))), # with 'flight' instead of first 'pk' it also doesn't work
)
答案 0 :(得分:1)
在Django中对.count()
的评估非常迫切,因此Django将尝试对flights.filter(zones__pk=F('pk')).distinct().count()
进行评估,并成功进行评估,因为F('pk')
将计算fligts
的数量,其中有zones
的主键与Flight
的主键相同。您将需要在子查询上使用OuterRef
[Django-doc]和.annotate(..)
。
但是,这使它变得太复杂了。您可以简单地使用以下注释:
from django.db.models import Q, Sum
Zone.objects.annotate(
count=Count('flight', distinct=True, filter=Q(flight__…))
)
filter=Q(flight__…)
是您的排期过滤器的一部分。因此,如果Flight
被假设的active=True
过滤,则可以使用:
Zone.objects.annotate(
count=Count('flight', distinct=True, filter=Q(flight__active=True))
)