模型C有到模型B的外键链接。模型B有到模型A的外键链接。也就是说,模型A实例可能有很多模型B实例,模型B可能有很多模型C实例。>
伪代码:
class A:
...
class B:
a = models.ForeignKey(A, ...)
class C:
b = models.ForeignKey(B, ...)
我想从数据库中检索模型A的元素的整个列表,并用它具有的B元素的数量注释它,其中它们各自的C元素的数量不是零(或任何随机数) )。
我尝试过:
A.objects.annotate(
at_least_one_count=Count('b', filter=Q(b__c__isnull=False))
)
据我所知,这应该是有效的。但是,返回的数字不正确(在实际情况下)。它返回的数字比没有过滤器的数字大,这显然是不可能的:
A.objects.annotate(
at_least_one_count=Count('b')
)
编辑:当我为每个A实例分别运行以下查询时,我得到的数字是相同的,这使我认为我的代码中可能存在错误:
A.objects.first().b_set.filter(c__isnull=False).__len__()
注意:我想在不使用SQL的情况下执行此查询。如果我必须利用Django提供的一些更高级的Pythonic工具,只要我保持面向对象,我会很乐意这样做。我试图摆脱对所有数据库操作使用原始SQL的方式,并使用Django ORM将它们全部重写。但是,它似乎过于复杂。
答案 0 :(得分:0)
答案很简单:应用转换为join语句的查询后,必须执行一个不同的on过滤器,这在Django中是通过对查询集调用.distinct(...)
来完成的。 < / p>
在这种情况下,如果您使用过滤器,并且过滤器对象受到明显的限制,那么您要使用:
...=Count('b', filter=Q(b__c__isnull=False), distinct=True)