Django 按月和年分组不起作用

Oli*_*ons 2 python django group-by

我已经通过谷歌搜索“django group by Month”阅读了这篇Django: Group by date (day,month,year)以及所有相关内容

如果我尝试“最干净”的解决方案 - 使用 Django 1.11,我最终会得到以下结果:

class Request(BaseModel):
    date_creation = models.DateTimeField(default=None,
                                         blank=True, null=True)

print([v for v in
       Request.objects.annotate(month=ExtractMonth('date_creation'),
                                year=ExtractYear('date_creation'),)
                      .values('month', 'year')
                      .annotate(total=Count('month'))
                      .values('month', 'year', 'total')
       ])
Run Code Online (Sandbox Code Playgroud)

结果不进行分组!我明白了:

[{'month': 6, 'year': 2017, 'total': 1}, 
 {'month': 7, 'year': 2017, 'total': 1}, 
 {'month': 7, 'year': 2017, 'total': 1}]
Run Code Online (Sandbox Code Playgroud)

我需要得到:

[{'month': 6, 'year': 2017, 'total': 1}, 
 {'month': 7, 'year': 2017, 'total': 2}]
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

print([v for v in
       Request.objects.extra({'month': 'strftime("%m", date_creation)',
                              'year': 'strftime("%Y", date_creation)'})
                      .values('month', 'year')
                      .annotate(total=Count('*'))
                      .values('month', 'year', 'total')
       ])
Run Code Online (Sandbox Code Playgroud)

然后我得到:

[{'month': '06', 'year': '2017', 'total': 1},
 {'month': '07', 'year': '2017', 'total': 1},
 {'month': '07', 'year': '2017', 'total': 1}]
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

Oli*_*ons 8

感谢 PyCharm,我发现了这个问题。如果没有那个 IDE,我真的不知道如何找到解决方案。我使用它的次数越多,我就越发现它的强大。然后我找到了解决方案:How can I remove Model Meta ordering in Django or get the raw queryset from thebuilt in Manager?

我的Request模型有一个父模型,它有一个字段date_creation和一个class Meta:with ordering = ['date_creation']。

因此,如果您没有order_by('field_xx')在查询中添加,那么 Django会自动添加以下内容:order_by('date_creation')。

因此我的查询看起来像:

SELECT
    (strftime("%m", date_creation)) AS "month",
    (strftime("%Y", date_creation)) AS "year",
    COUNT(*) AS "total" FROM "app_request"
  GROUP BY
    (strftime("%m", date_creation)),
    (strftime("%Y", date_creation)),
    "app_request"."date_creation"
Run Code Online (Sandbox Code Playgroud)

它破坏了查询。

解决方案是:

from django.db.models.functions.datetime import ExtractMonth, ExtractYear
print([v for v in
       Request.objects.annotate(month=ExtractMonth('date_creation'),
                                year=ExtractYear('date_creation'),)
                      .order_by()
                      .values('month', 'year')
                      .annotate(total=Count('*'))
                      .values('month', 'year', 'total')
       ])
Run Code Online (Sandbox Code Playgroud)

事实上,我的解决方案从一开始就有效!