Skip to content

More robust form rendering in the browsable API #4181

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

Merged
merged 1 commit into from
Jun 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions rest_framework/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,31 +472,37 @@ def get_rendered_html_form(self, data, view, method, request):
return

if existing_serializer is not None:
serializer = existing_serializer
try:
return self.render_form_for_serializer(existing_serializer)
except TypeError:
pass

if has_serializer:
if method in ('PUT', 'PATCH'):
serializer = view.get_serializer(instance=instance, **kwargs)
else:
serializer = 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'):
serializer = 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'}}
)
serializer = self._get_serializer(view.serializer_class, view,
request, **kwargs)

return self.render_form_for_serializer(serializer)

def render_form_for_serializer(self, serializer):
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'}}
)

def get_raw_data_form(self, data, view, method, request):
"""
Expand Down
53 changes: 53 additions & 0 deletions tests/browsable_api/test_form_rendering.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from django.test import TestCase

from rest_framework import generics, renderers, serializers, status
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory
from tests.models import BasicModel

factory = APIRequestFactory()


class BasicSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel


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 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 a view that returns a list of objects should
still successfully return the browsable API with a rendered form.

Regression test for https://github.com/tomchristie/django-rest-framework/pull/3164
"""
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)
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