From 11d8e4df88d6bd257379822f220e34ad3154f504 Mon Sep 17 00:00:00 2001 From: Dave Allan Date: Sat, 1 Apr 2017 20:31:27 -0400 Subject: [PATCH 1/3] PoC Add JSONBoundField to serializers (Fixes #4999) Per issue #4999, JSONFields are not rendered properly in the DRF browsable API HTML forms. This patch attempts to fix that behavior by introducing a JSONBoundField helper similar to the NestedBoundField helper. --- rest_framework/serializers.py | 5 ++++- rest_framework/utils/serializer_helpers.py | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index ba01c3434b..6e7e76fa85 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -38,7 +38,8 @@ 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 @@ def __getitem__(self, key): 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. diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 4734332af8..67b89634cd 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -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,12 @@ def as_form_field(self): return self.__class__(self._field, value, self.errors, self._prefix) +class JSONBoundField(BoundField): + def as_form_field(self): + value = json.dumps(self.value) + return self.__class__(self._field, value, self.errors, self._prefix) + + class NestedBoundField(BoundField): """ This `BoundField` additionally implements __iter__ and __getitem__ From 7a0bd1c4d1950f49d8e0710f535d3d15c2c43d79 Mon Sep 17 00:00:00 2001 From: Dave Allan Date: Wed, 26 Apr 2017 12:00:32 -0400 Subject: [PATCH 2/3] Use text area for JSON fields and indent JSON --- rest_framework/utils/field_mapping.py | 4 ++-- rest_framework/utils/serializer_helpers.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index b8817d9766..cc82492dc9 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -8,7 +8,7 @@ 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: diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 67b89634cd..2c4407d748 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -85,7 +85,7 @@ def as_form_field(self): class JSONBoundField(BoundField): def as_form_field(self): - value = json.dumps(self.value) + value = json.dumps(self.value, sort_keys=True, indent=4) return self.__class__(self._field, value, self.errors, self._prefix) From f56b1170643021b71eff5dba8f5e61f4de322b74 Mon Sep 17 00:00:00 2001 From: Dave Allan Date: Wed, 26 Apr 2017 13:48:49 -0400 Subject: [PATCH 3/3] Pass non-JSON serializable values through unmodified --- rest_framework/utils/serializer_helpers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 2c4407d748..d4c659e5fb 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -85,7 +85,11 @@ def as_form_field(self): class JSONBoundField(BoundField): def as_form_field(self): - value = json.dumps(self.value, sort_keys=True, indent=4) + 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) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy