相当于按年分组的Django ORM查询集?

Posted

技术标签:

【中文标题】相当于按年分组的Django ORM查询集?【英文标题】:Django ORM queryset equivalent to group by year-month? 【发布时间】:2021-04-30 00:17:21 【问题描述】:

我有一个 Django 应用程序,需要一些数据可视化,但我被 ORM 阻止了。

我有一个带有字段 created_at 的模型订单,我想在仪表板模板中使用图表栏(数字/年月)显示数据。 所以我需要从我的模型中聚合/注释数据,但确实找到了一个完整的解决方案。

我找到了 TruncMonth 的部分答案并阅读了有关序列化程序的信息,但想知道是否有最简单的解决方案与 Django ORM 可能性...

在 Postgresql 中是:

SELECT date_trunc('month',created_at), count(order_id) FROM "Orders" GROUP BY date_trunc('month',created_at) ORDER BY date_trunc('month',created_at);

"2021-01-01 00:00:00+01"    "2"
"2021-02-01 00:00:00+01"    "3"
"2021-03-01 00:00:00+01"    "3"
...

例子


1   "2021-01-04 07:42:03+01"
2   "2021-01-24 13:59:44+01"
3   "2021-02-06 03:29:11+01"
4   "2021-02-06 08:21:15+01"
5   "2021-02-13 10:38:36+01"
6   "2021-03-01 12:52:22+01"
7   "2021-03-06 08:04:28+01"
8   "2021-03-11 16:58:56+01"
9   "2022-03-25 21:40:10+01"
10  "2022-04-04 02:12:29+02"
11  "2022-04-13 08:24:23+02"
12  "2022-05-08 06:48:25+02"
13  "2022-05-19 15:40:12+02"
14  "2022-06-01 11:29:36+02"
15  "2022-06-05 02:15:05+02"
16  "2022-06-05 03:08:22+02"

预期结果


[
    
        "year-month": "2021-01",
        "number" : 2
    ,
    
        "year-month": "2021-03",
        "number" : 3
    ,
    
        "year-month": "2021-03",
        "number" : 3
    ,
    
        "year-month": "2021-03",
        "number" : 1
    ,
    
        "year-month": "2021-04",
        "number" : 2
    ,
    
        "year-month": "2021-05",
        "number" : 3
    ,
    
        "year-month": "2021-06",
        "number" : 3
    ,
]


我已经完成了,但我无法按日期订购:

Orders.objects.annotate(month=TruncMonth('created_at')).values('month').annotate(number=Count('order_id')).values('month', 'number').order_by()

<SafeDeleteQueryset [
   'month': datetime.datetime(2022, 3, 1, 0, 0, tzinfo=<UTC>), 'number': 4, 
   'month': datetime.datetime(2022, 6, 1, 0, 0, tzinfo=<UTC>), 'number': 2, 
   'month': datetime.datetime(2022, 5, 1, 0, 0, tzinfo=<UTC>), 'number': 1, 
   'month': datetime.datetime(2022, 1, 1, 0, 0, tzinfo=<UTC>), 'number': 5, 
   'month': datetime.datetime(2021, 12, 1, 0, 0, tzinfo=<UTC>), 'number': 1, 
   'month': datetime.datetime(2022, 7, 1, 0, 0, tzinfo=<UTC>), 'number': 1, 
   'month': datetime.datetime(2021, 9, 1, 0, 0, tzinfo=<UTC>), 'number': 2, 
   '...(remaining elements truncated)...'
]> 

【问题讨论】:

order_by('month') 没用? 【参考方案1】:

如果您有多年数据,请尝试在原始字段中添加 order_by。

from django.db.models import Sum
from django.db.models.functions import TruncMonth


Orders.objects.values(month=TruncMonth('created_at')).
    order_by("created_at").annotate(Sum('number')

【讨论】:

以上是关于相当于按年分组的Django ORM查询集?的主要内容,如果未能解决你的问题,请参考以下文章

python 之 Django框架(orm单表查询orm多表查询聚合查询分组查询F查询 Q查询事务Django ORM执行原生SQL)

[Django框架之ORM操作:多表查询,聚合查询分组查询F查询Q查询choices参数]

在 Django ORM 中按查询分组

Django中的聚合/分组查询/F/Q查询/orm执行原生sql语句/ ORM事务和锁

Python - Django - ORM 分组查询补充

$Django 聚合函数分组查询F,Q查询orm字段以及参数