Merge pull request #5042 from boxingwizards/i4999

PoC Add JSONBoundField to serializers (Fixes #4999)
This commit is contained in:
Tom Christie 2017-04-27 20:26:40 +01:00 committed by GitHub
commit 80d0ee563a
3 changed files with 17 additions and 3 deletions

View File

@ -38,7 +38,8 @@ from rest_framework.utils.field_mapping import (
get_relation_kwargs, get_url_kwargs
)
from rest_framework.utils.serializer_helpers import (
BindingDict, BoundField, NestedBoundField, ReturnDict, ReturnList
BindingDict, BoundField, JSONBoundField, NestedBoundField, ReturnDict,
ReturnList
)
from rest_framework.validators import (
UniqueForDateValidator, UniqueForMonthValidator, UniqueForYearValidator,
@ -521,6 +522,8 @@ class Serializer(BaseSerializer):
error = self.errors.get(key) if hasattr(self, '_errors') else None
if isinstance(field, Serializer):
return NestedBoundField(field, value, error)
if isinstance(field, JSONField):
return JSONBoundField(field, value, error)
return BoundField(field, value, error)
# Include a backlink to the serializer class on return objects.

View File

@ -8,7 +8,7 @@ from django.core import validators
from django.db import models
from django.utils.text import capfirst
from rest_framework.compat import DecimalValidator
from rest_framework.compat import DecimalValidator, JSONField
from rest_framework.validators import UniqueValidator
NUMERIC_FIELD_TYPES = (
@ -88,7 +88,7 @@ def get_field_kwargs(field_name, model_field):
if decimal_places is not None:
kwargs['decimal_places'] = decimal_places
if isinstance(model_field, models.TextField):
if isinstance(model_field, models.TextField) or (JSONField and isinstance(model_field, JSONField)):
kwargs['style'] = {'base_template': 'textarea.html'}
if isinstance(model_field, models.AutoField) or not model_field.editable:

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals
import collections
import json
from collections import OrderedDict
from django.utils.encoding import force_text
@ -82,6 +83,16 @@ class BoundField(object):
return self.__class__(self._field, value, self.errors, self._prefix)
class JSONBoundField(BoundField):
def as_form_field(self):
value = self.value
try:
value = json.dumps(self.value, sort_keys=True, indent=4)
except TypeError:
pass
return self.__class__(self._field, value, self.errors, self._prefix)
class NestedBoundField(BoundField):
"""
This `BoundField` additionally implements __iter__ and __getitem__