[
{'month_number':[1,2,3,4,5]},
{'month_number_2':[6,6,8,8,8,10]}
]
class Test(Modelbase):
student_id = models.IntegerField(null=True)
上面是模型,created_at是获取month_number的默认字段。
我使用了以下查询来过滤数据,但是使用它我们将不得不再循环以区分不同的月份。
Model.objects.filter(created_at__month__gte=3).values(*['student_id','created_at'])
我们可以一次性使用Django ORM吗?
答案 0 :(得分:3)
您可以使用groupby
的itertools:
from django.db.models import F, Func
from itertools import groupby
from operator import itemgetter
query = (Model.objects.annotate(month=Func(F('created_at'), function='MONTH'))
.filter(month__gte=3)
.order_by('month')
.values('student_id','month'))
result = {
m: [x['student_id'] for x in xs]
for m, xs in groupby(query, itemgetter('month'))
}
因此,我们首先生成一个构建注释的查询:我们使用Model
属性注释每个month
实例,该属性是created_at
字段的月份。
接下来,我们根据此month
列大于或等于3
的事实进行过滤,接下来我们按month
对查询集进行排序(这对于{{ 1}}仅在项目基于我们想要分组的元素形成组的情况下才起作用的函数。然后我们执行groupby
以使查询更有效。
然后我们执行values(..)
,以便我们在同一个月创建元素块。这将创建一个可迭代的2元组,其中月份编号为groupby(query, itemgetter('month'))
,m
是属于该组的可迭代字典。
我们将此迭代转换为字典,其中xs
映射到m
的列表。