Django 1.11.20获取每个ISO周和年度的行数

时间:2019-02-20 06:49:09

标签: python django

我需要获取每个ISO周和每年的项目数。我尝试了以下

    from django.db.models.functions import ExtractWeek, ExtractYear
    from django.db.models.aggregates import Count

    count = myModel.objects.annotate(year=ExtractYear('created_at')) \
        .annotate(week=ExtractWeek('created_at')) \
        .values('year','week') \
        .annotate(count=Count('week'))

但是我的结果是

<QuerySet [{'year': 2019, 'week': 7, 'count': 1}, {'year': 2019, 'week': 7, 'count': 1}, {'year': 2019, 'week': 7, 'count': 1}, {'year': 2019, 'week': 7, 'count': 1}.......

如何获得更改,所以我的结果是:

提前谢谢

3 个答案:

答案 0 :(得分:1)

问题不是缺少的order_by,而是相反的情况:默认的order_by可能通过myModel字段指定了默认的排序方式而出现在ordering中向破坏您分组的查询添加了另一个字段。相关的Django文档为here

您可以通过在查询后附加.order_by()来摆脱它,也可以像回答中一样指定其他顺序。

这是一次又一次的吸引人(包括我自己)的障碍,所以我不希望在模型中不使用默认排序。

PS:当事情没有按计划进行时,通常可以通过检查上次执行的查询来检查生成的SQL:

django.db.connection.queries[-1]

...或通过询问刚刚定义的查询的SQL:

str(my_query.query)

如果您喜欢自己所看到的内容,但又不喜欢SQL格式化的方式,请查看sqlparse

答案 1 :(得分:0)

您可以使用TruncWeekTruncYear

from django.db.models.functions import TruncWeek, TruncYear

count_for_week = myModel.objects.annotate(
    week=TruncWeek('created_at'),
).values(
    'week',
).annotate(
    count=Count('id'),
)

count_for_year = myModel.objects.annotate(
    year=TruncYear('created_at'),
).values(
    'year',
).annotate(
    count=Count('id'),
)

因此,您将拥有:

 <QuerySet [{'week': datetime.datetime(2019, 2, 18, 0, 0, tzinfo=<UTC>), 'count': 1}]>

其中weekyear值将是该范围的开始日期时间:每年的一周

您可以在Django文档here中阅读更多详细信息。

答案 2 :(得分:0)

我发现了,我忘了订购结果

from django.db.models.functions import ExtractWeek, ExtractYear
from django.db.models.aggregates import Count

count = myModel.objects.annotate(year=ExtractYear('created_at')) \
    .annotate(week=ExtractWeek('created_at')) \
    .values('year','week') \
    .annotate(count=Count('id')).order_by('count')

<QuerySet [{'year': 2019, 'week': 7, 'count': 8}]>