diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 70c210c16..9584c0be3 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1766,6 +1766,9 @@ class JSONField(Field): 'invalid': _('Value must be valid JSON.') } + # Workaround for isinstance calls when importing the field isn't possible + _is_jsonfield = True + def __init__(self, *args, **kwargs): self.binary = kwargs.pop('binary', False) super(JSONField, self).__init__(*args, **kwargs) diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 6b662a66c..e162673dd 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -118,6 +118,8 @@ class NestedBoundField(BoundField): error = self.errors.get(key) if isinstance(self.errors, dict) else None if hasattr(field, 'fields'): return NestedBoundField(field, value, error, prefix=self.name + '.') + elif getattr(field, '_is_jsonfield', False): + return JSONBoundField(field, value, error, prefix=self.name + '.') return BoundField(field, value, error, prefix=self.name + '.') def as_form_field(self): diff --git a/tests/test_bound_fields.py b/tests/test_bound_fields.py index e588ae623..f14a9641d 100644 --- a/tests/test_bound_fields.py +++ b/tests/test_bound_fields.py @@ -91,6 +91,10 @@ class TestSimpleBoundField: assert rendered_packed == expected_packed +class CustomJSONField(serializers.JSONField): + pass + + class TestNestedBoundField: def test_nested_empty_bound_field(self): class Nested(serializers.Serializer): @@ -117,14 +121,31 @@ class TestNestedBoundField: class Nested(serializers.Serializer): bool_field = serializers.BooleanField() null_field = serializers.IntegerField(allow_null=True) + json_field = serializers.JSONField() + custom_json_field = CustomJSONField() class ExampleSerializer(serializers.Serializer): nested = Nested() - serializer = ExampleSerializer(data={'nested': {'bool_field': False, 'null_field': None}}) + serializer = ExampleSerializer( + data={'nested': { + 'bool_field': False, 'null_field': None, + 'json_field': {'bool_item': True, 'number': 1, 'text_item': 'text'}, + 'custom_json_field': {'bool_item': True, 'number': 1, 'text_item': 'text'}, + }}) assert serializer.is_valid() assert serializer['nested']['bool_field'].as_form_field().value == '' assert serializer['nested']['null_field'].as_form_field().value == '' + assert serializer['nested']['json_field'].as_form_field().value == '''{ + "bool_item": true, + "number": 1, + "text_item": "text" +}''' + assert serializer['nested']['custom_json_field'].as_form_field().value == '''{ + "bool_item": true, + "number": 1, + "text_item": "text" +}''' def test_rendering_nested_fields_with_none_value(self): from rest_framework.renderers import HTMLFormRenderer