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): """ 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)
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: