基于 this SO question about counting forgein keys , 我有个问题。这是我的模型:
class Type(models.Model):
is_bulk = models.BooleanField()
class Component(models.Model):
parent = models.ForgeinKey(Type, related_name="components")
我想编写一个包含所有类型的查询集,除了那些具有 is_bulk=True 且没有组件的查询集。如果 is_bulk=False,则应包括在内。如果 is_bulk=True 并且您有 1 个以上链接的组件,那么您就被包括在内。否则,您将被排除在外。
根据答案,我尝试了这个查询集:
Type.objects.annotate(num_components=Count('components')).exclude(is_bulk=True, num_components=0)
但它没有返回任何结果。
然而,这意味着应该有结果:
>>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
[(False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0)]
所有 Type 对象都具有 is_bulk=False 并且它们都具有 0 个组件。来自阅读the .exclude(…) documentation ,它应该是 NOT(is_bulk=True AND num_components=0),对于每种类型都应该是 True。正确的? (我这里是不是搞错了,如果是,正确的queryset是什么)
如果不是,为什么这个查询集返回 [],而它应该返回所有这些?这是 Django 1.3 中的错误吗?
请您参考如下方法:
我已通过将查询集更改为以下内容来解决此问题:
types_qs.annotate(num_components=Count('components')).filter(Q(is_bulk=False) | (Q(is_bulk=True) & Q(num_components__gt=0)))
这行得通,但我不明白为什么我原来的行不通。嗯。
