使用Django每小时对行进行分组

Ank*_*pli 2 django postgresql django-1.8

我一直试图将表的结果分组为使用的每小时格式DateTimeField.

SQL:

SELECT strftime('%H', created_on), count(*)
FROM users_test
GROUP BY strftime('%H', created_on);
Run Code Online (Sandbox Code Playgroud)

此查询工作正常,但相应的Django查询没有.

Django查询我试过:

Test.objects.extra({'hour': 'strftime("%%H", created_on)'}).values('hour').annotate(count=Count('id'))
# SELECT (strftime("%H", created_on)) AS "hour", COUNT("users_test"."id") AS "count" FROM "users_test" GROUP BY (strftime("%H", created_on)), "users_test"."created_on" ORDER BY "users_test"."created_on" DESC
Run Code Online (Sandbox Code Playgroud)

它通过"users_test"添加了额外的组."created_on",我猜这会产生错误的结果.

如果有人能解释我并提供解决方案,那将是很棒的.

环境:

  • Python 3
  • Django 1.8.1

提前致谢

引用(可能重复)(但没有帮助):

dan*_*era 6

要修复它,请附加order_by()到查询链.这将覆盖模型Meta默认排序.像这样:

Test
.objects
.extra({'hour': 'strftime("%%H", created_on)'})
.order_by()                                        #<------ here
.values('hour')
.annotate(count=Count('id'))
Run Code Online (Sandbox Code Playgroud)

在我的环境中(Postgres也):

>>> print ( Material
         .objects
         .extra({'hour': 'strftime("%%H", data_creacio)'})
         .order_by()
         .values('hour')
         .annotate(count=Count('id'))
         .query )

  SELECT (strftime("%H", data_creacio)) AS "hour", 
         COUNT("material_material"."id") AS "count" 
    FROM "material_material" 
GROUP BY (strftime("%H", data_creacio))
Run Code Online (Sandbox Code Playgroud)

通过django docs了解更多信息:

如果您不希望将任何排序应用于查询,甚至不需要默认排序,请调用order_by(),不带参数.

附注:使用extra()可能会为您的代码引入SQL注入漏洞.谨慎使用此功能并转义用户可以引入的任何参数.与文档比较:

警告

每当你使用extra()时都应该非常小心.每次使用它时,都应该使用params来转义用户可以控制的任何参数,以防止SQL注入攻击.请阅读有关SQL注入保护的更多信息.

  • 非常感谢您拯救我的一天. (2认同)