【问题标题】:django annotate - conditional countdjango annotate - 条件计数
【发布时间】:2016-10-31 04:17:48
【问题描述】:

我有一个名为“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,而我希望它遍历指向商店项目的所有报价项目并计算它们,如果它们符合条件(单独) .

如何实现?

【问题讨论】:

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


    【解决方案1】:

    我正在做类似的任务。对我来说,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,
            )
        )
    

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

    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 可以通过itemgroup 或直接与quoteitems 相关联。

    【讨论】:

      【解决方案2】:

      您需要将所有内容包装在 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()
                  )
              )
          )
      

      这基本上将内部Case 语句的所有0s 和1s 相加,从而计算匹配数。

      【讨论】:

        猜你喜欢
        • 2021-04-10
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 2022-08-16
        • 1970-01-01
        • 2017-07-25
        • 2021-01-30
        • 2014-05-18
        相关资源
        最近更新 更多