django 如何聚合筛选列表apiview查询集并一次性返回值

e4eetjau  于 2022-11-18  发布在  Go
关注(0)|答案(1)|浏览(130)

如何对筛选的查询集执行聚合并只返回一次值?

下面是我现有的代码。在序列化器中,当然PZ.objects.all()使它聚合所有项。我不知道如何从序列化器级别获得queryset。要使合计值只出现一次,在视图中添加一个字段是个好主意。然而,重写def list():使过滤停止工作。
我需要这个,因为我正在使用一个表,该表显示具有筛选功能的文档。此外,还将分页。例如,在选择创建日期范围后,必须对文档的值求和。
查看方式:

class PZListAPIView(ListAPIView):
    queryset = PZ.objects.all()
    serializer_class = PZModelSerializer
    filterset_fields = {
        'id': ['exact', 'in', 'contains', 'range']
    }

串行器:

class PZModelSerializer(serializers.ModelSerializer):
    net_value_sum = serializers.SerializerMethodField('get_net_value_sum')
    class Meta:
        model = PZ
        fields = '__all__'
    
    def get_net_value_sum(self, obj):
        return PZ.objects.aggregate(Sum('net_value'))['net_value__sum']

回应:

[
    {
        "id": 41,
        "net_value_sum": 28.0,
        "status": "C",
        "net_value": "6.00"
    },
    {
        "id": 42,
        "net_value_sum": 28.0,
        "status": "S",
        "net_value": "10.00"
    }
]

期望的响应:

[
    "net_value_sum": 16.0,
    {
        "id": 41,
        "status": "C",
        "net_value": "6.00"
    },
    {
        "id": 42,
        "status": "S",
        "net_value": "10.00"
    }
]
i7uq4tfw

i7uq4tfw1#

我自己设法找到了这个问题的解决方案。在返回过滤后的queryset时,需要覆盖'def list():'方法。然后在视图中的这个queryset上返回聚合值。代码如下所示:

class PZListAPIView(ListAPIView):
    queryset = PZ.objects.all()
    serializer_class = PZModelSerializer
    filterset_fields = {
        'id': ['exact', 'in', 'contains', 'range']
    }
    
    def get_queryset(self):
        return PZ.objects.all()

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        
        net_value = queryset.aggregate(Sum('net_value'))['net_value__sum']
        return Response([{'net_value': net_value},serializer.data])

相关问题