From 342a940708fb2509dde9f798f57449464f306f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20R=2E=20Sede=C3=B1o?= Date: Mon, 13 Jul 2015 15:02:09 -0400 Subject: [PATCH 1/2] A test for a POST that returns multiple objects, which triggers issue #2918 --- tests/test_generics.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_generics.py b/tests/test_generics.py index 2e47df50fb..334988e783 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -64,6 +64,16 @@ class FKInstanceView(generics.RetrieveUpdateDestroyAPIView): serializer_class = ForeignKeySerializer +class ManyPostView(generics.GenericAPIView): + queryset = BasicModel.objects.all() + serializer_class = BasicSerializer + renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer) + + def post(self, request, *args, **kwargs): + serializer = self.get_serializer(self.get_queryset(), many=True) + return Response(serializer.data, status.HTTP_200_OK) + + class SlugBasedInstanceView(InstanceView): """ A model with a slug-field. @@ -542,3 +552,30 @@ def get(self, request): request = factory.get('/') with pytest.raises(RuntimeError): view(request).render() + + +class TestManyPostView(TestCase): + def setUp(self): + """ + Create 3 BasicModel instances. + """ + items = ['foo', 'bar', 'baz'] + for item in items: + BasicModel(text=item).save() + self.objects = BasicModel.objects + self.data = [ + {'id': obj.id, 'text': obj.text} + for obj in self.objects.all() + ] + self.view = ManyPostView.as_view() + + def test_post_many_post_view(self): + """ + POST request to ManyPostView should return a list of objects. + """ + data = {} + request = factory.post('/', data, format='json') + with self.assertNumQueries(1): + response = self.view(request).render() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 3) From 8ee63e90b87989c5c22d92e3440ec3e689ca8bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20R=2E=20Sede=C3=B1o?= Date: Tue, 23 Feb 2016 13:01:46 -0500 Subject: [PATCH 2/2] Collect serialziers to try when rendering the Browsable API The first one should work, if it doesn't because of Issue #2918, then the second one should work. If no collected serializer worked, raise the exception generated by the last one. --- rest_framework/renderers.py | 54 +++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 024f0eb8ba..9740a0409f 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -473,32 +473,40 @@ def get_rendered_html_form(self, data, view, method, request): ): return + serializers = [] if existing_serializer is not None: - serializer = existing_serializer + serializers.append(existing_serializer) + + if has_serializer: + if method in ('PUT', 'PATCH'): + serializers.append(view.get_serializer(instance=instance, **kwargs)) + else: + serializers.append(view.get_serializer(**kwargs)) else: - if has_serializer: - if method in ('PUT', 'PATCH'): - serializer = view.get_serializer(instance=instance, **kwargs) - else: - serializer = view.get_serializer(**kwargs) + # at this point we must have a serializer_class + if method in ('PUT', 'PATCH'): + serializers.append(self._get_serializer(view.serializer_class, view, + request, instance=instance, **kwargs)) else: - # at this point we must have a serializer_class - if method in ('PUT', 'PATCH'): - serializer = self._get_serializer(view.serializer_class, view, - request, instance=instance, **kwargs) - else: - serializer = self._get_serializer(view.serializer_class, view, - request, **kwargs) - - if hasattr(serializer, 'initial_data'): - serializer.is_valid() - - form_renderer = self.form_renderer_class() - return form_renderer.render( - serializer.data, - self.accepted_media_type, - {'style': {'template_pack': 'rest_framework/horizontal'}} - ) + serializers.append(self._get_serializer(view.serializer_class, view, + request, **kwargs)) + + for serializer in serializers: + try: + if hasattr(serializer, 'initial_data'): + serializer.is_valid() + + form_renderer = self.form_renderer_class() + return form_renderer.render( + serializer.data, + self.accepted_media_type, + {'style': {'template_pack': 'rest_framework/horizontal'}} + ) + except TypeError: + pass + # If none of the rendering attempts succeeded, raise the TypeError generated by the last + # attempt. + raise def get_raw_data_form(self, data, view, method, request): """ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy