Как объединить отфильтрованный список listapiview queryset и вернуть значение один раз
Как выполнить агрегацию на отфильтрованных наборах запросов и вернуть значение только один раз?
Мой существующий код ниже. В сериализаторе, конечно же, PZ.objects.all() заставляет его агрегировать все элементы. Я не знаю, как получить кверисет с уровня сериализатора. Чтобы общее значение отображалось один раз, было бы неплохо добавить поле в представлении. Однако переопределение def list(): заставляет фильтрацию перестать работать.
Мне это нужно, потому что я работаю над таблицей, которая показывает документы с возможностью фильтрации. Кроме того, будет присутствовать пагинация. После выбора, например, диапазона дат создания, значения документов должны суммироваться.
Вид:
class PZListAPIView(ListAPIView):
queryset = PZ.objects.all()
serializer_class = PZModelSerializer
filterset_fields = {
'id': ['exact', 'in', 'contains', 'range']
}
Serializer:
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"
}
]
Мне удалось найти решение этой проблемы самостоятельно. Нужно переопределить метод 'def list():' при возврате отфильтрованного набора запросов. Затем по этому кверисету в представлении возвращаем агрегированное значение. Код выглядит следующим образом:
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])