我们可以使用 django orm 来获得如下所示的输出吗
Can we use django orm to get a output like shown below
[
{'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 一次完成吗?
你可以使用 itertools 的 groupby
:
<b>from django.db.models import F, Func
from itertools import groupby
from operator import itemgetter</b>
query = (Model.objects<b>.annotate(month=Func(F('created_at'), function='MONTH'))</b>
.filter(month__gte=3)
<b>.order_by('month')</b>
.values('student_id','month'))
result = {
m: [x['student_id'] for x in xs]
for m, xs in <b>groupby(query, itemgetter('month'))</b>
}
因此,我们首先生成一个构造注释的查询:我们用 month
属性注释每个 Model
实例,该属性是 created_at
字段的月份。
接下来我们根据 month
列大于或等于 3
的事实进行过滤,接下来我们按 month
对查询集进行排序(这对于groupby
函数仅在项目基于我们要分组的元素形成组的情况下起作用。然后我们执行 values(..)
以使查询更高效。
然后我们执行 groupby(query, itemgetter('month'))
所以我们创建了具有相同月份的元素块。这将创建一个包含 m
月份编号的 2 元组的可迭代对象,以及 xs
属于该组的字典的可迭代对象。
我们将这个可迭代对象转换为字典,其中 m
映射到 student_id
的列表。
[
{'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 一次完成吗?
你可以使用 itertools 的 groupby
:
<b>from django.db.models import F, Func
from itertools import groupby
from operator import itemgetter</b>
query = (Model.objects<b>.annotate(month=Func(F('created_at'), function='MONTH'))</b>
.filter(month__gte=3)
<b>.order_by('month')</b>
.values('student_id','month'))
result = {
m: [x['student_id'] for x in xs]
for m, xs in <b>groupby(query, itemgetter('month'))</b>
}
因此,我们首先生成一个构造注释的查询:我们用 month
属性注释每个 Model
实例,该属性是 created_at
字段的月份。
接下来我们根据 month
列大于或等于 3
的事实进行过滤,接下来我们按 month
对查询集进行排序(这对于groupby
函数仅在项目基于我们要分组的元素形成组的情况下起作用。然后我们执行 values(..)
以使查询更高效。
然后我们执行 groupby(query, itemgetter('month'))
所以我们创建了具有相同月份的元素块。这将创建一个包含 m
月份编号的 2 元组的可迭代对象,以及 xs
属于该组的字典的可迭代对象。
我们将这个可迭代对象转换为字典,其中 m
映射到 student_id
的列表。