【问题标题】:Django QuerySet with exclude & annotate not returning any results带有排除和注释的 Django QuerySet 不返回任何结果
【发布时间】:2023-04-02 22:38:02
【问题描述】:

基于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 中的错误吗?

【问题讨论】:

  • 您可能希望打印 Queryset 的查询属性,以便读取 SQL Django 输出。
  • 您可以尝试一次使用一个参数进行排除,看看问题是is_bulk=Truenum_components=0还是一起使用。
  • 你的models.py中有一个错字parent = models.ForgeinKey(Type)应该是ForeignKey

标签: python django django-queryset django-orm


【解决方案1】:

我已通过将查询集更改为:

types_qs.annotate(num_components=Count('components')).filter(Q(is_bulk=False) | (Q(is_bulk=True) & Q(num_components__gt=0)))

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

【讨论】:

    【解决方案2】:

    我试过这个例子,我认为你需要的是在你的领域声明一个related_name

    class Component(models.Model):
        parent = models.ForgeinKey(Type, related_name='components')
    

    应该这样做

    更新

    根据您的示例:

    >>> [(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)]
    

    还有我的:

    >>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
    [(False, 3), (False, 0), (False, 1), (False, 4), (True, 2), (True, 3), (True, 1), (True, 1), (False, 2), (True, 7), (True, 0), (False, 0)]
    

    我假设您没有符合查询集要求的对象:

    Type.objects.annotate(num_components=Count('components')).exclude(is_bulk=True, num_components=0)
    

    你的结果:

    []
    

    这是我的结果:

    [<Type: Type object>, <Type: Type object>, <Type: Type object>, <Type: Type object>]
    

    【讨论】:

    • 我已经在我的模型中做到了,问题就出现了。我已经更新了问题
    猜你喜欢
    • 1970-01-01
    • 2020-09-25
    • 2014-10-13
    • 1970-01-01
    • 2018-02-13
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多