Skip to main content
 首页 » 编程设计

python之带有排除和注释的 Django QuerySet 不返回任何结果

2025年05月04日32jiqing9006

基于 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))) 

这行得通,但我不明白为什么我原来的行不通。嗯。