From 95ae92ef23859b45d03bcc2facf04fab0acee09d Mon Sep 17 00:00:00 2001 From: Berkant Date: Tue, 9 Mar 2021 14:34:18 +0300 Subject: [PATCH] Fix #7706 (#7724) Handle non-dict values for NestedSerializer during BrowsableAPI rendering. --- rest_framework/utils/serializer_helpers.py | 4 ++-- tests/test_bound_fields.py | 27 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index b18fbe0df..cd0373adc 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -1,5 +1,5 @@ from collections import OrderedDict -from collections.abc import MutableMapping +from collections.abc import Mapping, MutableMapping from django.utils.encoding import force_str @@ -101,7 +101,7 @@ class NestedBoundField(BoundField): """ def __init__(self, field, value, errors, prefix=''): - if value is None or value == '': + if value is None or value == '' or not isinstance(value, Mapping): value = {} super().__init__(field, value, errors, prefix) diff --git a/tests/test_bound_fields.py b/tests/test_bound_fields.py index dc5ab542f..dec8793c3 100644 --- a/tests/test_bound_fields.py +++ b/tests/test_bound_fields.py @@ -163,6 +163,33 @@ class TestNestedBoundField: rendered_packed = ''.join(rendered.split()) assert rendered_packed == expected_packed + def test_rendering_nested_fields_with_not_mappable_value(self): + from rest_framework.renderers import HTMLFormRenderer + + class Nested(serializers.Serializer): + text_field = serializers.CharField() + + class ExampleSerializer(serializers.Serializer): + nested = Nested() + + serializer = ExampleSerializer(data={'nested': 1}) + assert not serializer.is_valid() + renderer = HTMLFormRenderer() + for field in serializer: + rendered = renderer.render_field(field, {}) + expected_packed = ( + '
' + 'Nested' + '' + '' + '' + '' + '
' + ) + + rendered_packed = ''.join(rendered.split()) + assert rendered_packed == expected_packed + class TestJSONBoundField: def test_as_form_fields(self):