1

I'm overriding the def get_queryset(self) to aggregate averages, sums, etc, of a model. My challenge is that I want to return these values but it is not a queryset so I get the following error: django.template.response.ContentNotRenderedError: The response content must be rendered before it can be iterated over.. My question is how can I return these values since they are not a queryset.

Here is my code:

class OrderMetrics(generics.ListCreateAPIView ):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

    def get_queryset(self):
        ...

        context = [ 
            {
            'data': round(current_total),
            'percent': abs(total_delta_percentage),
            },
            {
            'data': current_count,
            'percent': abs(avergae_delta_percentage),
            },
        ]

        print(context)
        return Response(context, status=status.HTTP_200_OK)



# print(context) returns the following:
# [{'data': 138378, 'percent': 132}, {'data': 11, 'percent': 16}]

I have seen several other similar questions but they don't address how to do this: ContentNotRenderedError: The response content must be rendered before it can be iterated over. Django REST and ContentNotRenderedError : The response content must be rendered before it can be iterated over

alkadelik
  • 526
  • 1
  • 7
  • 18
  • `get_queryset`returns a `QuerySet`. Normally an `APIView`. – Willem Van Onsem May 20 '23 at 09:47
  • The get_queryset method should return a queryset, not a response object – Ramziya Nisham May 20 '23 at 09:47
  • Can you also share the `Order` model and the `OrderSerializer` and exactly *what* you aim to do. It looks very odd that the data is just a number of records? – Willem Van Onsem May 20 '23 at 09:49
  • @WillemVanOnsem yes I know. But how can I achieve what I want to achieve? This question shows the full code: https://stackoverflow.com/questions/76293062/unboundlocalerror-local-variable-current-referenced-before-assignment/76293293#76293293 – alkadelik May 20 '23 at 09:55

1 Answers1

1

The get_queryset is supposed to return, as the name suggests… a QuerySet, not a response object. You can try to pass a list, since it is iterable as well, but likely if pagination, serialization, etc. is performed, it will eventually fail.

You can implement the list method yourself, with:

class OrderMetrics(generics.ListCreateAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

    def list(self, request, *args, **kwargs):
        context = [
            {
                'data': round(current_total),
                'percent': abs(total_delta_percentage),
            },
            {
                'data': current_count,
                'percent': abs(average_delta_percentage),
            },
        ]
        return Response(context, status=status.HTTP_200_OK)

but it is unclear to me then why you use a GenericAPIView with a model and a serializer, since you will only use these for the create use case, and it is a bit odd to create Orders in an endpoint that shows metrics of orders.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555