我需要获取每个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}.......
如何获得更改,所以我的结果是:
提前谢谢
答案 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)
您可以使用TruncWeek
和TruncYear
:
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}]>
其中week
或year
值将是该范围的开始日期时间:每年的一周
您可以在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}]>