Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
53 views
in Technique[技术] by (71.8m points)

Django Rest Framework: append value to ListAPIView

StackOverflow community,

I've got the following serializer and view:

serializers.py

class PricetrendSerializer(serializers.ModelSerializer):
timestamp = serializers.DateTimeField()
average_price = serializers.IntegerField()

class Meta:
    model = Cars
    fields = ('timestamp', 'average_price')

views.py

class Pricetrend(generics.ListAPIView):
queryset = Cars.objects.annotate(timestamp=TruncMonth('timestamp')).values('timestamp').annotate(average_price=Avg('price'))
serializer_class = PricetrendSerializer
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
filterset_class = PriceFilter
search_fields = ['description']
ordering_fields = ['timestamp', 'average_price']
ordering = ['timestamp']
permission_classes = (permissions.IsAuthenticated,)

Which is giving me the following output:

    {
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "timestamp": "2020-04-01T00:00:00",
      "average_price": 90274
    },
    {
      "timestamp": "2020-05-01T00:00:00",
      "average_price": 99253
    }
    ]
    }   

I would like to also aggregate the total average price and add it to the output, e.g.:

    {
  "count": 2,
  "next": null,
  "previous": null,
  "total_average_price": 125000,
  "results": [
    {
      "timestamp": "2020-04-01T00:00:00",
      "average_price": 90274
    },
    {
      "timestamp": "2020-05-01T00:00:00",
      "average_price": 99253
    }
    ]
    }   

Unfortunately, I do not know how this could be done as adding it to the serializer will result in having the total_average_price in every JSON object. I also tried to override the ListAPIView (get function) but this killed the built-in pagination :(

I hope that somebody is able to help me find a neat way to solve this.

question from:https://stackoverflow.com/questions/65891271/django-rest-framework-append-value-to-listapiview

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can create a custom pagination class and override its get_paginated_response. In paginations.py:

class PricesPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page'

    def get_paginated_response(self, data):
        prices = [dict(item)['average_price'] for item in data]
        page_price_avg = sum(prices)/ len(prices)
        return Response({
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'count': self.page.paginator.count,
            'page_price_avg': page_price_avg,
            'results': data,
        })

In views.py, set your custom pagination:

class PriceTrendListView(ListAPIView):
    pagination_class = PricesPagination
    serializer_class = PriceTrendSerializer
    queryset = Car.objects.all()

Then, you will be able to see the average price for each page.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...