Djang官方orm语句按照月份分组
django官方提供的一个orm语法
1 from django.db.models.functions import TruncMonth 2 Sales.objects 3 .annotate(month=TruncMonth('timestamp')) # Truncate to month and add to select list 4 .values('month') # Group By month 5 .annotate(c=Count('id')) # Select the count of the grouping 6 .values('month', 'c') # (might be redundant, haven't tested) select month and count
实际应用:
举个例子:假设我们需要统计每个月写的文章数,就可以通过按照月份分组,配合annotate分组查询以及聚合函数Count来查询,具体代码如下:
1 # 按照年月统计当前用户的所有文章
from django.db.models.functions import TruncMonth
2 date_list = models.Article.objects.filter(blog=blog_obj).annotate(month=TruncMonth('create_time')).values('month').annotate(count_num=Count('pk')).values_list('month', 'count_num') 3 4 步骤解析: 5 date_list = models.Article.objects.filter(blog=blog_obj) 拿到queryset对象 6 .annotate(month=TruncMonth('create_time')) 按照月份分组(指定时间字段) 7 .values('month') 拿到按月份分组后的数据 8 .annotate(count_num=Count('pk')) 根据id或者pk字段统计(主键字段) 9 .values_list('month', 'count_num') 拿到月份分组,和统计数量
同理,通过上面的例子,我们也可以举一反三,通过年、日等来进行分组
有关Trunc的详细用法,见官方文档:https://docs.djangoproject.com/en/3.2/ref/models/database-functions/#trunc
注意:有时候我们通过 TruncMonth 来截取日期的时候会报错:Database returned an invalid datetime value. Are time zone definitions for your database installed?
这是因为时区问题,这时我们需要在 django 的 settings.py 配置文件中进行如下配置:
1 # 修改前 2 3 LANGUAGE_CODE = ‘en-us’ 4 5 TIME_ZONE = ‘UTC’ 6 7 USE_I18N =True 8 9 USE_L10N =True 10 11 USE_TZ = True # 统一全球的时间 12 13 14 # 修改后 15 16 LANGUAGE_CODE =‘zh-hans’ 17 18 TIME_ZONE =‘Asia/Shanghai’ 19 20 USE_I18N =True 21 22 USE_L10N =True 23 24 USE_TZ =False