Skip to content

@list_route post cannot return serializer(qs, many=True) #2918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sainttail opened this issue May 7, 2015 · 5 comments
Closed

@list_route post cannot return serializer(qs, many=True) #2918

sainttail opened this issue May 7, 2015 · 5 comments

Comments

@sainttail
Copy link

I have a @list_route that look like this

@list_route(methods=['post'])
    def test(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

but when I try to POST to .../events/test/ via browsable API
calling without browsable API is working normally.

I got exactly same error message as #2607 (ListSerializer object is not iterable)

I don't know why this happen? because I want post action to return update objects
However, if i change to this @list_route(methods=['get']) or @list_route(methods=['patch']) it is working fine

My serializer class is a normal class that extends form ModelSerializer

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
@sainttail sainttail changed the title @list_route post cannot return serializer(many=True) @list_route post cannot return serializer(qs, many=True) May 7, 2015
@tomchristie
Copy link
Member

Could you provide the stack trace you're seeing when you make the POST request?

but when I try to POST to .../events/test/ via browsable API
calling without browsable API is working normally.

I didn't understand this - which case works, which case doesn't?

@sainttail
Copy link
Author

Here is a stack trace when I made a POST request via browsable API in web browser

Traceback (most recent call last):
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/core/handlers/base.py", line 137, in get_response
    response = response.render()
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/template/response.py", line 103, in render
    self.content = self.rendered_content
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/rest_framework/response.py", line 59, in rendered_content
    ret = renderer.render(self.data, media_type, context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/rest_framework/renderers.py", line 657, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/rest_framework/renderers.py", line 634, in get_context
    'post_form': self.get_rendered_html_form(data, view, 'POST', request),
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/rest_framework/renderers.py", line 503, in get_rendered_html_form
    [('template', 'rest_framework/api_form.html')]
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/rest_framework/renderers.py", line 357, in render
    return template.render(context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/template/base.py", line 148, in render
    return self._render(context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/test/utils.py", line 88, in instrumented_test_render
    return self.nodelist.render(context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/template/base.py", line 844, in render
    bit = self.render_node(node, context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/template/debug.py", line 80, in render_node
    return node.render(context)
  File "/Users/eak/Desktop/env/sakahama/lib/python2.7/site-packages/django/template/defaulttags.py", line 161, in render
    values = list(values)
TypeError: 'ListSerializer' object is not iterable

Here is a screenshot when error occurs
screen shot 2015-05-09 at 1 55 10 am

BUT It works when I POST via curlcommand

curl -X POST -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8080/api/events/test/

Definitely something wrong with form generate on browsable API because I am returning multiple objects for POST?

@tomchristie
Copy link
Member

Definitely something wrong with form generate on browsable API because I am returning multiple objects for POST?

Indeed - almost certainly due to the browsable API calling get_serializer which by default will not use many=True for POST requests.

You could resolve this by either:

  • Modifying the get_serializer() method so that it uses many=True for POST requests.
  • Use GET requests for your endpoint instead.

It's possible that we could try to guard against this kind of case more gracefully, but I don't see it as sufficiently worth prioritizing so I'm going to close this off for now.

@mikofski
Copy link

mikofski commented Nov 3, 2015

@tomchristie I'm trying to modify get_serializer for a similar api, but I can't figure it out

  • similar to @asedeno
  • using POST
  • returns multiple objects
  • works fine as json, but not as html form in browsable api, I get my ListSerializer is not iterable
  • input serializer, a python class object, is not the same as output serializer, a django query set
  • I have to use POST because I'm replacing an older API and I'm not allowed to breaking it.

@khamaileon
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants