mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 01:26:53 +03:00
Fixes BrowsableAPIRenderer
for usage with ListSerializer
. (#7530)
Renders list of items in raw_data_form and does not renders form in template while using with `ListSerializer` (`many=True`).
This commit is contained in:
parent
376a5cbbba
commit
02d9bfc2dd
|
@ -506,6 +506,9 @@ class BrowsableAPIRenderer(BaseRenderer):
|
|||
return self.render_form_for_serializer(serializer)
|
||||
|
||||
def render_form_for_serializer(self, serializer):
|
||||
if isinstance(serializer, serializers.ListSerializer):
|
||||
return None
|
||||
|
||||
if hasattr(serializer, 'initial_data'):
|
||||
serializer.is_valid()
|
||||
|
||||
|
@ -555,10 +558,13 @@ class BrowsableAPIRenderer(BaseRenderer):
|
|||
context['indent'] = 4
|
||||
|
||||
# strip HiddenField from output
|
||||
is_list_serializer = isinstance(serializer, serializers.ListSerializer)
|
||||
serializer = serializer.child if is_list_serializer else serializer
|
||||
data = serializer.data.copy()
|
||||
for name, field in serializer.fields.items():
|
||||
if isinstance(field, serializers.HiddenField):
|
||||
data.pop(name, None)
|
||||
data = [data] if is_list_serializer else data
|
||||
content = renderer.render(data, accepted, context)
|
||||
# Renders returns bytes, but CharField expects a str.
|
||||
content = content.decode()
|
||||
|
|
|
@ -633,6 +633,9 @@ class BrowsableAPIRendererTests(URLPatternsTestCase):
|
|||
class AuthExampleViewSet(ExampleViewSet):
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
class SimpleSerializer(serializers.Serializer):
|
||||
name = serializers.CharField()
|
||||
|
||||
router = SimpleRouter()
|
||||
router.register('examples', ExampleViewSet, basename='example')
|
||||
router.register('auth-examples', AuthExampleViewSet, basename='auth-example')
|
||||
|
@ -640,6 +643,62 @@ class BrowsableAPIRendererTests(URLPatternsTestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.renderer = BrowsableAPIRenderer()
|
||||
self.renderer.accepted_media_type = ''
|
||||
self.renderer.renderer_context = {}
|
||||
|
||||
def test_render_form_for_serializer(self):
|
||||
with self.subTest('Serializer'):
|
||||
serializer = BrowsableAPIRendererTests.SimpleSerializer(data={'name': 'Name'})
|
||||
form = self.renderer.render_form_for_serializer(serializer)
|
||||
assert isinstance(form, str), 'Must return form for serializer'
|
||||
|
||||
with self.subTest('ListSerializer'):
|
||||
list_serializer = BrowsableAPIRendererTests.SimpleSerializer(data=[{'name': 'Name'}], many=True)
|
||||
form = self.renderer.render_form_for_serializer(list_serializer)
|
||||
assert form is None, 'Must not return form for list serializer'
|
||||
|
||||
def test_get_raw_data_form(self):
|
||||
with self.subTest('Serializer'):
|
||||
class DummyGenericViewsetLike(APIView):
|
||||
def get_serializer(self, **kwargs):
|
||||
return BrowsableAPIRendererTests.SimpleSerializer(**kwargs)
|
||||
|
||||
def get(self, request):
|
||||
response = Response()
|
||||
response.view = self
|
||||
return response
|
||||
|
||||
post = get
|
||||
|
||||
view = DummyGenericViewsetLike.as_view()
|
||||
_request = APIRequestFactory().get('/')
|
||||
request = Request(_request)
|
||||
response = view(_request)
|
||||
view = response.view
|
||||
|
||||
raw_data_form = self.renderer.get_raw_data_form({'name': 'Name'}, view, 'POST', request)
|
||||
assert raw_data_form['_content'].initial == '{\n "name": ""\n}'
|
||||
|
||||
with self.subTest('ListSerializer'):
|
||||
class DummyGenericViewsetLike(APIView):
|
||||
def get_serializer(self, **kwargs):
|
||||
return BrowsableAPIRendererTests.SimpleSerializer(many=True, **kwargs) # returns ListSerializer
|
||||
|
||||
def get(self, request):
|
||||
response = Response()
|
||||
response.view = self
|
||||
return response
|
||||
|
||||
post = get
|
||||
|
||||
view = DummyGenericViewsetLike.as_view()
|
||||
_request = APIRequestFactory().get('/')
|
||||
request = Request(_request)
|
||||
response = view(_request)
|
||||
view = response.view
|
||||
|
||||
raw_data_form = self.renderer.get_raw_data_form([{'name': 'Name'}], view, 'POST', request)
|
||||
assert raw_data_form['_content'].initial == '[\n {\n "name": ""\n }\n]'
|
||||
|
||||
def test_get_description_returns_empty_string_for_401_and_403_statuses(self):
|
||||
assert self.renderer.get_description({}, status_code=401) == ''
|
||||
|
|
Loading…
Reference in New Issue
Block a user