【问题标题】:Can we use django orm to get a output like shown below我们可以使用 django orm 来获得如下所示的输出吗
【发布时间】:2018-06-06 09:35:36
【问题描述】:
[
    {'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 是获取月份编号的默认字段。

我已经使用下面的查询来过滤数据,但是使用它我们将不得不再次循环以区分不同的月份。

Model.objects.filter(created_at__month__gte=3).values(*['student_id','created_at'])

我们可以一次性使用 Django ORM 做到这一点吗?

【问题讨论】:

    标签: django django-orm django-1.9


    【解决方案1】:

    您可以使用 itertools 的 groupby

    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'))
    }

    因此,我们首先生成一个查询,并在其中构造一个注解:我们使用month 属性来注解每个Model 实例,该属性是created_at 字段的月份。

    接下来我们根据month 列大于或等于3 的事实进行过滤,接下来我们按month 对查询集进行排序(这对于仅适用于的groupby 函数很重要根据我们要分组的元素将项目分组。然后我们执行values(..) 以提高查询效率。

    然后我们执行groupby(query, itemgetter('month')),因此我们创建了同一月份的元素块。这将创建一个 2 元组的迭代,其中 m 是月份编号,xs 是属于该组的字典的迭代。

    我们将这个可迭代对象转换成一个字典,其中m 映射到student_ids 的列表。

    【讨论】:

    • 对不起,我之前应该提过这个,我使用的是 Django 1.9
    • @BharatBittu:语法已更新,应该可以在 1.9 中使用。
    • 感谢您的解释。但是,我收到以下查询响应 - SyntaxError: invalid syntax ('created_at'))filter.(month__gte=3)
    • @BharatBittu:是​​的,我打错了。现在应该解决这个问题。
    • 由于这是 Django 1.9,由于没有 ExtractMonth,我们将不得不使用 Extract
    猜你喜欢
    • 2013-01-01
    • 2021-06-22
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    相关资源
    最近更新 更多