如何根据日期过滤来获取本周与上一周的数据来自QuerySet?

时间:2017-05-19 09:44:17

标签: python django aggregate-functions

我有以下两个带注释的QuerySet,我通过从数据集中提取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}]), ,然后执行注释来单独生成。我想在归还它们之前将它们合并在一起。

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')

预期:

Dept

或者,是否有一种直接聚合的方法,以便直接从一组带有日期字段的项目中直接进行聚合?以下是我当前正在生成两个QuerySet的方法:

Widgets

有没有办法将这两个注释链接在一起,这样我最终会为每个Widgets分组和排序一个QuerySet,具体取决于本周使用了多少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') ,还有添加了一个字段,显示前一周使用了多少var t = {a: {b: {c: 3} }, d: 4 }; path (t, ''); function path(t, sofar) { if (Object.keys(t).length === 0) console.log(sofar.substr(1)); var keys = Object.keys(t); for (var i = 0 ; i < keys.length ; ++i) { path(t[keys[i]], sofar+'.'+keys[i]); } }

我在想这样的事情:

{{1}}

2 个答案:

答案 0 :(得分:2)

检查条件聚合:

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 :(得分:1)

您的想法似乎对您的案例是正确的。为了达到您的需求,您可以应用以下内容:

  1. 小但有用的是range查找,可让您在两个值之间进行过滤
  2. 要限制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') 参数,您需要使用conditional aggregation
  3. 最后,您的查询将如下所示:

    dept

    根据评论编辑:

    在这种情况下不需要此步骤,这有助于构建注释以对已过滤的dept字段的值求和。

    1. 我会利用F()表达式获取注释中每个Count字段的值,并使用Sum函数代替library(httr) library(xml2) get_description <- function(ISBN) { httr::GET("http://www.librarything.com/services/rest/1.1/", query=list(method = "librarything.ck.getwork", isbn = ISBN, apikey = Sys.getenv("LIBRARYTHING_API_KEY"))) -> res stop_for_status(res) res <- content(res, as="text") doc <- read_xml(res) desc <- xml_find_all(doc, ".//*[@name='description']") if (length(desc) > 0) { xml_text(desc) # or whatever you need } else { "" # or whatever you want to return if not found } } isbns <- c("9788426379696", "9788426348593") purrr::map_chr(isbns, get_description) 来将这些值添加到一起。