我们可以使用django orm来获得如下所示的输出

时间:2018-06-06 09:35:36

标签: django django-orm django-1.9

[
    {'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吗?

1 个答案:

答案 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的列表。