django annotate - 条件计数

时间:2016-06-28 17:46:19

标签: python django django-models django-filter django-annotate

我有一个名为'StoreItem'的模型和一个名为'QuoteItem'的模型。 QuoteItem指向StoreItem。

我正在尝试注释一个计数器,指出有多少报价项指向商店商品,但是有条件适用于报价项目。

我试过这样的事情:

items = items.annotate(
            quote_count=Count(
                Case(
                    When(quoteitem__lookup_date__in=this_week, then=1), 
                    output_field=IntegerField()
                )
            )
        )

'items'是StoreItems的查询集。 'this_week'是代表本周的日期列表(这是我尝试应用的过滤器)。在我使日期工作之后,我想为这个条件计数添加更多过滤器,但让我们开始吧。

无论如何我得到的更像是一个布尔值 - 如果符合条件的引用项存在,无论我有多少,计数器都是1.否则,将为0.

看起来Count(Case())只检查是否存在任何项目,如果存在则返回1,而我希望它迭代指向商店项目的所有报价项目并计算它们,如果它们符合条件(个别地)。

我该如何实现?

2 个答案:

答案 0 :(得分:8)

你需要用Sum语句而不是Count来包装所有内容(我觉得Count完全有点奇怪):

from django.db.models import Case, IntegerField, Sum, When

items = items.annotate(
        quote_count=Sum(
            Case(
                When(quoteitem__lookup_date__in=this_week, then=1), 
                output_field=IntegerField()
            )
        )
    )

这基本上会为内部0语句添加所有1Case s,从而计算匹配数。

答案 1 :(得分:0)

我正在做类似的任务。对我来说,Sum上的Case/When由于我加入了多少桌子而无法正常工作(这已超过计数)。结束如下:

from django.db.models import Case, IntegerField, Count, When, F

items = items.annotate(
        quote_count=Count(
            Case(
                When(quoteitem__lookup_date__in=this_week, then=F('quoteitem__id'), 
            ),
            distinct=True,
        )
    )

在我的情况下,我实际上必须将两个Count加在一起,如:

items = items.annotate(
        quote_count=Count(
            Case(
                When(quoteitem__lookup_date__in=this_week, then=F('quoteitem__id'), 
            ),
            distinct=True,
        )
    ) + Count (
            Case(
                When(itemgroup__lookup_date__in=this_week, then=F('itemgroup__quoteitem__id'), 
            ),
            distinct=True,
        )

假设items可以通过quoteitems或直接与itemgroup相关联。