8

I have a slightly complicated APIView which makes that I can't use a generic ListAPIView to return a queryset. But I can't seem to simply serialize a simple Django queryset using a ModelSerializer, even when I set many=True.

Somehow this doesn't work:

serializers.py:

class SomeModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = SomeModel
        fields = ['some_field']

views.py:

from rest_framework.response import Response

class SomeAPIView(APIView):
    serializer_class = SomeInputSerializer

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            # first some business logic, then return results
            results = SomeModel.objects.all()
            output_serializer = SomeModelSerializer(results, many=True)
            return Response(output_serializer.data)

All I keep getting is: 'ListSerializer' object is not iterable.

What am I doing wrong?

Error:

/projectfolder/venv/lib/python2.7/site-packages/django/template/defaulttags.py in render
            try:
                values = self.sequence.resolve(context, True)
            except VariableDoesNotExist:
                values = []
            if values is None:
                values = []
            if not hasattr(values, '__len__'):
                values = list(values) ...
            len_values = len(values)
            if len_values < 1:
                return self.nodelist_empty.render(context)
            nodelist = []
            if self.is_reversed:
                values = reversed(values)

values = list(values) seems to be responsible for the error

4
  • This code looks fine. Could you provide more of your actual code? Which line throws the error? Commented Apr 13, 2016 at 7:13
  • @ilse2005 The last one. I can actually print output_serializer.data to the console with no problems, but get the error when returning the Response object. I've included an error log. Commented Apr 13, 2016 at 9:38
  • From where do you import Response? Commented Apr 13, 2016 at 9:51
  • @ilse2005 rest_framework.response, updated the example Commented Apr 13, 2016 at 14:14

3 Answers 3

7

Was running into the same problem as you did. I found a quick and simple fix for the error: Copy the serializer data to a new array and return that.

results = SomeModel.objects.all()

output_serializer = SomeModelSerializer(results, many=True)    
data = output_serializer.data[:]

return Response(data)

This works for me, hopefully for you as well.

Sign up to request clarification or add additional context in comments.

Comments

6

Below works for me using an as_view() url:

 class ListCreateMemberViewSet(generics.ListCreateAPIView):
        """
        API endpoint that allows multiple members to be created.
        """
        queryset = Member.objects.none()
        serializer_class = MemberSerializer

    def get_queryset(self):
         queryset = Member.objects.all()
         return queryset

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list))
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        results = Member.objects.all()
        output_serializer = MemberSerializer(results, many=True)
        data = output_serializer.data[:]
        return Response(data)

Comments

1

The error is a result of trying to run a list on a serializer directly.

For example, this would raise the above exception:

results = Member.objects.all()
output_serializer = MemberSerializer(results, many=True)
all_results = list(output_serializer) # this line here
all_results += output_serializer  # or this line here

And this would not (difference is that we are listing output_serializer.data instead of output_serializer):

results = Member.objects.all()
output_serializer = MemberSerializer(results, many=True)
all_results = list(output_serializer.data)
all_results += output_serializer.data

I have the feeling that in the original question, the example code was not 100% matching the actual code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.