簡體   English   中英

如何通過日期過濾以從QuerySet中獲得本周與上周的計數?

[英]How can I filter by date to get this week vs previous week Counts from a QuerySet?

我有以下兩個帶注釋的QuerySet,它們是通過從數據集中提取this_wkprev_wk然后執行注釋而分別生成的。 在返回之前,我想將它們合並在一起。

data = {
    'this_wk': QuerySet([{'this_total': 3, 'dept': 2}, 
                         {'this_total': 2, 'dept': 1}, 
                         {'this_total': 1, 'dept': 3}]),
    'prev_wk': QuerySet([{'prev_total': 2, 'dept': 3}])}

預期:

QuerySet([{'this_total': 3, 'prev_total': None, 'dept': 2},
          {'this_total': 2, 'prev_total': None, 'dept': 1}, 
          {'this_total': 1, 'prev_total': 2, 'dept': 3}]),

或者,是否有一種直接匯總的方法,這樣我就可以直接從帶有日期字段的一組項目中進行選擇? 這是我當前生成兩個QuerySet的方式:

previous_items = Widget.objects.filter(start__gte=prev_start).filter(start__lte=prev_end)
prev_ranking = previous_items.values('dept').annotate(prev_total=Count('dept'))

this_items = Widget.objects.filter(start__gte=this_start
    ).filter(start__lte=this_end)
this_ranking = this_items.values('dept'
    ).annotate(this_total=Count('dept')
    ).order_by('-this_total')

有沒有一種方法可以將這兩個注釋鏈接在一起,所以我最終將單個QuerySet分組並根據本周使用的Widgets數量對每個Dept排名,而且還添加了一個字段,指出了它是多少個Widgets前一周使用過?

我在想這樣的事情:

items = Widget.objects.filter(start__gte=prev_start
    ).filter(start__lte=this_end
    ).annotate(prev_total=Count('dept')  # can I restrict this to the previous week?
    ).annotate(this_total=Count('dept')  # can I restrict this to the current week?
    ).order_by('-this_total')

查看條件聚合:

https://docs.djangoproject.com/en/1.10/ref/models/conditional-expressions/#conditional-aggregation

items = (Widget.objects.filter(start__range=(prev_start, this_end))
         .values('dept')
         .annotate(prev_total=Count(Case(When(start__lte=prev_end, then='dept'), output_field=IntegerField())),
                   this_total=Count(Case(When(start__gte=this_start, then='dept'), output_field=IntegerField()))
                   )
         .order_by('-this_total'))

您的想法似乎適合您的情況。 為了實現您所需要的,您可以應用以下方法:

  1. range查找雖然小巧但很有用,它使您可以在兩個值之間進行過濾
  2. 要限制您的annotate參數,您需要使用條件聚合

最后,您的查詢將如下所示:

items = Widget.objects.filter(start__range=(prev_start, this_end))
                      .values('dept')
                      .annotate(
                           prev_total=Count(
                               Case(
                                   When(start__lte=prev_end, then=1)),                 
                                   output_field=IntegerField())),
                           this_total=Count(
                               Case(
                                   When(start__gte=this_start, then=1), 
                                   output_field=IntegerField())))
                       .order_by('-this_total')

根據評論進行編輯:

在這種情況下,無需執行此步驟,這將有助於構建注釋以匯總過濾后的dept字段的值。

  1. 我將利用F()表達式獲取注釋內每個dept字段的值,並使用Sum函數而不是Count將這些值加在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM