首页 > 解决方案 > django rest 框架使用 ArrayAgg 和 GROUP BY 进行注释

问题描述

我想使用 django postgres 函数 ArrayAgg,但我也想将它与 GROUP BY 一起使用。sql 真的很容易编写,但我无法让它与 ORM 或原始 sql 一起使用

SELECT field1, ARRAY_AGG(field2)
FROM table1
GROUP BY field1

使用 orm 我认为这样的事情可能会奏效

subquery = Subquery(
           models.Model1.objects
           .filter(field1=OuterRef('field1'))
           .values('field2')
           .aggregate(field3=ArrayAgg('field2'))
           .values('field3')
)
queryset = queryset.annotate(field3=subquery)

但它没有outerref错误(我尝试了很多排列)

并且使用原始查询我可以让它工作,但是它会返回我猜测的所有字段,因为 RawQueryset 和 defer 之类的东西不起作用,所以所有字段都被查询并返回。

rawqueryset = models.Model1.objects.raw(
    'SELECT m.id, t.field1, t.field3 '
    'FROM ('
        'SELECT field1, array_agg(field2) as field3 '
        'FROM app_table1 '
        'GROUP BY frame_id '
    ') t LEFT OUTER JOIN app_table m ON m.field1 = t.frame_id',
    []
)
serializer = serializers.Model1(rawqueryset, many=True)
return Response(serializer.data)

有没有办法做到这一点?

标签: pythondjangodjango-modelsdjango-rest-frameworkdjango-views

解决方案


我能够使用原始 sql 让它工作

rawqueryset = models.Model1.objects.raw(
    'SELECT m.id, t.field1, t.field3 '
    'FROM ('
        'SELECT field1, array_agg(field2) as field3 '
        'FROM app_table1 '
        'GROUP BY frame_id '
    ') t LEFT OUTER JOIN app_table m ON m.field1 = t.frame_id',
    []
)
serializer = serializers.Model1(rawqueryset, many=True, context={'request': request})
return Response(serializer.data)

缺少的是将请求对象添加到传递的上下文中。


推荐阅读