mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Added JSONField. Closes #3170.
This commit is contained in:
parent
bae47b7f36
commit
10dbf1316f
|
@ -459,6 +459,14 @@ You can also use the declarative style, as with `ListField`. For example:
|
|||
class DocumentField(DictField):
|
||||
child = CharField()
|
||||
|
||||
## JSONField
|
||||
|
||||
A field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON encoded strings.
|
||||
|
||||
**Signature**: `JSONField(binary)`
|
||||
|
||||
- `binary` - If set to `True` then the field will output and validate a JSON encoded string, rather that a primitive data structure. Defaults to `False`.
|
||||
|
||||
---
|
||||
|
||||
# Miscellaneous fields
|
||||
|
|
|
@ -64,6 +64,13 @@ except ImportError:
|
|||
postgres_fields = None
|
||||
|
||||
|
||||
# JSONField is only supported from 1.9 onwards
|
||||
try:
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
except ImportError:
|
||||
JSONField = None
|
||||
|
||||
|
||||
# django-filter is optional
|
||||
try:
|
||||
import django_filters
|
||||
|
|
|
@ -5,6 +5,7 @@ import copy
|
|||
import datetime
|
||||
import decimal
|
||||
import inspect
|
||||
import json
|
||||
import re
|
||||
import uuid
|
||||
from collections import OrderedDict
|
||||
|
@ -1522,6 +1523,31 @@ class DictField(Field):
|
|||
])
|
||||
|
||||
|
||||
class JSONField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _('Value must be valid JSON.')
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.binary = kwargs.pop('binary', False)
|
||||
super(JSONField, self).__init__(*args, **kwargs)
|
||||
|
||||
def to_internal_value(self, data):
|
||||
try:
|
||||
if self.binary:
|
||||
return json.loads(data)
|
||||
else:
|
||||
json.dumps(data)
|
||||
except (TypeError, ValueError):
|
||||
self.fail('invalid')
|
||||
return data
|
||||
|
||||
def to_representation(self, value):
|
||||
if self.binary:
|
||||
return json.dumps(value)
|
||||
return value
|
||||
|
||||
|
||||
# Miscellaneous field types...
|
||||
|
||||
class ReadOnlyField(Field):
|
||||
|
|
|
@ -21,6 +21,7 @@ from django.utils.functional import cached_property
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from rest_framework.compat import DurationField as ModelDurationField
|
||||
from rest_framework.compat import JSONField as ModelJSONField
|
||||
from rest_framework.compat import postgres_fields, unicode_to_repr
|
||||
from rest_framework.utils import model_meta
|
||||
from rest_framework.utils.field_mapping import (
|
||||
|
@ -790,6 +791,8 @@ class ModelSerializer(Serializer):
|
|||
}
|
||||
if ModelDurationField is not None:
|
||||
serializer_field_mapping[ModelDurationField] = DurationField
|
||||
if ModelJSONField is not None:
|
||||
serializer_field_mapping[ModelJSONField] = JSONField
|
||||
serializer_related_field = PrimaryKeyRelatedField
|
||||
serializer_url_field = HyperlinkedIdentityField
|
||||
serializer_choice_field = ChoiceField
|
||||
|
|
|
@ -1525,6 +1525,62 @@ class TestUnvalidatedDictField(FieldValues):
|
|||
field = serializers.DictField()
|
||||
|
||||
|
||||
class TestJSONField(FieldValues):
|
||||
"""
|
||||
Values for `JSONField`.
|
||||
"""
|
||||
valid_inputs = [
|
||||
({
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': None
|
||||
}, {
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': None
|
||||
}),
|
||||
]
|
||||
invalid_inputs = [
|
||||
({'a': set()}, ['Value must be valid JSON.']),
|
||||
]
|
||||
outputs = [
|
||||
({
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': 3
|
||||
}, {
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': 3
|
||||
}),
|
||||
]
|
||||
field = serializers.JSONField()
|
||||
|
||||
|
||||
class TestBinaryJSONField(FieldValues):
|
||||
"""
|
||||
Values for `JSONField` with binary=True.
|
||||
"""
|
||||
valid_inputs = [
|
||||
('{"a": 1, "3": null, "b": ["some", "list", true, 1.23]}', {
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': None
|
||||
}),
|
||||
]
|
||||
invalid_inputs = [
|
||||
('{"a": "unterminated string}', ['Value must be valid JSON.']),
|
||||
]
|
||||
outputs = [
|
||||
({
|
||||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': None
|
||||
}, '{"a": 1, "3": null, "b": ["some", "list", true, 1.23]}'),
|
||||
]
|
||||
field = serializers.JSONField(binary=True)
|
||||
|
||||
|
||||
# Tests for FieldField.
|
||||
# ---------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user