mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Render JSON fields with proper indentation in browsable API forms. (#6243)
* Fix JSONBoundField usage on nested serializers (#6211) * Unify JSONBoundField as_form_field output between py2 and py3 When using json.dumps with indenting, in python2 the default formatting prints whitespace after commas (,) and python3 does not. This can be unified with the separators keyword argument.
This commit is contained in:
parent
ff625ecff5
commit
b256c46cb1
|
@ -1764,6 +1764,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)
|
||||
self.encoder = kwargs.pop('encoder', None)
|
||||
|
|
|
@ -87,7 +87,12 @@ class JSONBoundField(BoundField):
|
|||
# value will be a JSONString, rather than a JSON primitive.
|
||||
if not getattr(value, 'is_json_string', False):
|
||||
try:
|
||||
value = json.dumps(self.value, sort_keys=True, indent=4)
|
||||
value = json.dumps(
|
||||
self.value,
|
||||
sort_keys=True,
|
||||
indent=4,
|
||||
separators=(',', ': '),
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
return self.__class__(self._field, value, self.errors, self._prefix)
|
||||
|
@ -115,6 +120,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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user