Skip to content

Commit 922e767

Browse files
committed
Fix JSONBoundField usage on nested serializers (#6211)
1 parent 1c3f796 commit 922e767

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

rest_framework/fields.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,9 @@ class JSONField(Field):
17661766
'invalid': _('Value must be valid JSON.')
17671767
}
17681768

1769+
# Workaround for isinstance calls when importing the field isn't possible
1770+
_is_jsonfield = True
1771+
17691772
def __init__(self, *args, **kwargs):
17701773
self.binary = kwargs.pop('binary', False)
17711774
super(JSONField, self).__init__(*args, **kwargs)

rest_framework/utils/serializer_helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ def __getitem__(self, key):
118118
error = self.errors.get(key) if isinstance(self.errors, dict) else None
119119
if hasattr(field, 'fields'):
120120
return NestedBoundField(field, value, error, prefix=self.name + '.')
121+
elif getattr(field, '_is_jsonfield', False):
122+
return JSONBoundField(field, value, error, prefix=self.name + '.')
121123
return BoundField(field, value, error, prefix=self.name + '.')
122124

123125
def as_form_field(self):

tests/test_bound_fields.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class ExampleSerializer(serializers.Serializer):
9191
assert rendered_packed == expected_packed
9292

9393

94+
class CustomJSONField(serializers.JSONField):
95+
pass
96+
97+
9498
class TestNestedBoundField:
9599
def test_nested_empty_bound_field(self):
96100
class Nested(serializers.Serializer):
@@ -117,14 +121,31 @@ def test_as_form_fields(self):
117121
class Nested(serializers.Serializer):
118122
bool_field = serializers.BooleanField()
119123
null_field = serializers.IntegerField(allow_null=True)
124+
json_field = serializers.JSONField()
125+
custom_json_field = CustomJSONField()
120126

121127
class ExampleSerializer(serializers.Serializer):
122128
nested = Nested()
123129

124-
serializer = ExampleSerializer(data={'nested': {'bool_field': False, 'null_field': None}})
130+
serializer = ExampleSerializer(
131+
data={'nested': {
132+
'bool_field': False, 'null_field': None,
133+
'json_field': {'bool_item': True, 'number': 1, 'text_item': 'text'},
134+
'custom_json_field': {'bool_item': True, 'number': 1, 'text_item': 'text'},
135+
}})
125136
assert serializer.is_valid()
126137
assert serializer['nested']['bool_field'].as_form_field().value == ''
127138
assert serializer['nested']['null_field'].as_form_field().value == ''
139+
assert serializer['nested']['json_field'].as_form_field().value == '''{
140+
"bool_item": true,
141+
"number": 1,
142+
"text_item": "text"
143+
}'''
144+
assert serializer['nested']['custom_json_field'].as_form_field().value == '''{
145+
"bool_item": true,
146+
"number": 1,
147+
"text_item": "text"
148+
}'''
128149

129150
def test_rendering_nested_fields_with_none_value(self):
130151
from rest_framework.renderers import HTMLFormRenderer

0 commit comments

Comments
 (0)