【问题标题】:Django Rest Framework: append value to ListAPIViewDjango Rest Framework:将值附加到 ListAPIView
【发布时间】:2021-04-29 15:24:50
【问题描述】:

StackOverflow 社区,

我有以下序列化程序和视图:

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,)

这给了我以下输出:

    {
  "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
    }
    ]
    }   

我还想汇总总平均价格并将其添加到输出中,例如:

    {
  "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
    }
    ]
    }   

不幸的是,我不知道如何做到这一点,因为将其添加到序列化程序会导致每个 JSON 对象中都有 total_average_price。我还尝试覆盖 ListAPIView (获取函数),但这杀死了内置分页:(

我希望有人能够帮助我找到一个巧妙的方法来解决这个问题。

【问题讨论】:

    标签: django django-rest-framework django-views drf-queryset


    【解决方案1】:
    from rest_framework import pagination
    from rest_framework.response import Response
    
    
    class CustomPagination(pagination.PageNumberPagination):
        def get_paginated_response(self, data):
            return Response({
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                'total_average_price': 125000,
                'results': data,
            })
    
    
    class Pricetrend(generics.ListAPIView):
        queryset = Cars.objects.annotate(...)
        serializer_class = PricetrendSerializer
        pagination_class = CustomPagination
    

    【讨论】:

      【解决方案2】:

      您可以创建自定义分页类并覆盖其get_paginated_response。在 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,
              })
      

      在views.py中,设置你的自定义分页:

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

      然后,您将能够看到每个页面的平均价格。

      【讨论】:

        猜你喜欢
        • 2013-05-21
        • 1970-01-01
        • 2016-05-07
        • 1970-01-01
        • 2016-05-06
        • 1970-01-01
        • 1970-01-01
        • 2022-06-14
        • 1970-01-01
        相关资源
        最近更新 更多