Django ORM分组依据,并找到每个分组的最新项目(窗口功能)

标签 django django-models django-rest-framework django-orm window-functions

说我们有一个如下模型

class Cake(models.Model):

    baked_on = models.DateTimeField(auto_now_add=True)
    cake_name = models.CharField(max_length=20)

现在,在同一天烘烤了多个Cake,我需要一个查询,该查询将向我返回一个月度蛋糕报告,该报告包含该月的每一天以及该天烘烤的第一个和最后一个蛋糕的名称。

例如,如果数据是这样的:
baked_on        cake_name
11 Jan 12:30    Vanilla
11 Jan 14:30    Strawberry
11 Jan 20:45    Avocado
12 Jan 09:05    Raspberry
12 Jan 16:30    Sprinkles
12 Jan 20:11    Chocolate

我的查询的输出应如下所示
date    first     last
11 Jan  Vanilla   Avocado
12 Jan  Raspberry Chocolate

我应该如何在一个ORM调用中执行此操作?

最佳答案

Django 2.0引入了针对此类查询的窗口函数。您的问题的简单答案将是:

Cake.objects.annotate(
    first_cake=Window(
        expression=FirstValue('cake_name'),
        partition_by=[TruncDate('baked_on')],
        order_by=F('baked_on').asc(),
    ),
    last_cake=Window(
        expression=FirstValue('cake_name'),
        partition_by=[TruncDate('baked_on')],
        order_by=F('baked_on').desc(),
    ),
    day=TruncDate('baked_on'),
).distinct().values_list('day', 'first_cake', 'last_cake')

为什么在FirstValue中使用last_cake?这是因为默认情况下,窗口查询将遍历每一行并且不会向前看,因此对于每一行,最后一行将等于当前行。结合使用last_row和降序排序将解决此问题。或者,或者您可以定义窗口查询应适用的框架:
Cake.objects.annotate(
    first_cake=Window(
        expression=FirstValue('cake_name'),
        partition_by=[TruncDate('baked_on')],
        order_by=F('baked_on').asc(),
    ),
    last_cake=Window(
        expression=LastValue('cake_name'),
        partition_by=[TruncDate('baked_on')],
        order_by=F('baked_on').asc(),
        frame=ValueRange(),
    ),
    day=TruncDate('baked_on'),
).distinct().values_list('day', 'first_cake', 'last_cake')

关于Django ORM分组依据,并找到每个分组的最新项目(窗口功能),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49367130/

相关文章:

Django Rest Framework Postman token 认证

python - 从 Django View 中的 HttpResponse 检索 JSON

python - Django:显示 "featured"项目?

django模型ManyToManyField不通过管理器

django - 在 Django Rest Framework 中接收 Base64 编码的图像并保存到 ImageField

Django REST Framework - 在 ApiClient 的序列化器测试中设置请求

python - 使用 django.contrib.gis.measure.D 时出现 GeoDjango dwithin 错误

python - 如何解决类型错误: RelatedManager object is not iterable

django - django中按字段类型统计数据库条目

django - 在 Django 中保存嵌套表单