mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Allow JSONField encoder customization. (#6713)
This commit is contained in:
parent
afb678433b
commit
514033815d
|
@ -501,9 +501,10 @@ Note that the child field **must** be an instance of `CharField`, as the hstore
|
|||
|
||||
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 binary strings.
|
||||
|
||||
**Signature**: `JSONField(binary)`
|
||||
**Signature**: `JSONField(binary, encoder)`
|
||||
|
||||
- `binary` - If set to `True` then the field will output and validate a JSON encoded string, rather than a primitive data structure. Defaults to `False`.
|
||||
- `encoder` - Use this JSON encoder to serialize input object. Defaults to `None`.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1746,6 +1746,7 @@ class JSONField(Field):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.binary = kwargs.pop('binary', False)
|
||||
self.encoder = kwargs.pop('encoder', None)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def get_value(self, dictionary):
|
||||
|
@ -1767,14 +1768,14 @@ class JSONField(Field):
|
|||
data = data.decode()
|
||||
return json.loads(data)
|
||||
else:
|
||||
json.dumps(data)
|
||||
json.dumps(data, cls=self.encoder)
|
||||
except (TypeError, ValueError):
|
||||
self.fail('invalid')
|
||||
return data
|
||||
|
||||
def to_representation(self, value):
|
||||
if self.binary:
|
||||
value = json.dumps(value)
|
||||
value = json.dumps(value, cls=self.encoder)
|
||||
value = value.encode()
|
||||
return value
|
||||
|
||||
|
|
|
@ -1232,6 +1232,11 @@ class ModelSerializer(Serializer):
|
|||
# `allow_blank` is only valid for textual fields.
|
||||
field_kwargs.pop('allow_blank', None)
|
||||
|
||||
if postgres_fields and isinstance(model_field, postgres_fields.JSONField):
|
||||
# Populate the `encoder` argument of `JSONField` instances generated
|
||||
# for the PostgreSQL specific `JSONField`.
|
||||
field_kwargs['encoder'] = getattr(model_field, 'encoder', None)
|
||||
|
||||
if postgres_fields and isinstance(model_field, postgres_fields.ArrayField):
|
||||
# Populate the `child` argument on `ListField` instances generated
|
||||
# for the PostgreSQL specific `ArrayField`.
|
||||
|
|
|
@ -13,6 +13,7 @@ from collections import OrderedDict
|
|||
import django
|
||||
import pytest
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.core.validators import (
|
||||
MaxValueValidator, MinLengthValidator, MinValueValidator
|
||||
)
|
||||
|
@ -452,15 +453,17 @@ class TestPosgresFieldsMapping(TestCase):
|
|||
def test_json_field(self):
|
||||
class JSONFieldModel(models.Model):
|
||||
json_field = postgres_fields.JSONField()
|
||||
json_field_with_encoder = postgres_fields.JSONField(encoder=DjangoJSONEncoder)
|
||||
|
||||
class TestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = JSONFieldModel
|
||||
fields = ['json_field']
|
||||
fields = ['json_field', 'json_field_with_encoder']
|
||||
|
||||
expected = dedent("""
|
||||
TestSerializer():
|
||||
json_field = JSONField(style={'base_template': 'textarea.html'})
|
||||
json_field = JSONField(encoder=None, style={'base_template': 'textarea.html'})
|
||||
json_field_with_encoder = JSONField(encoder=<class 'django.core.serializers.json.DjangoJSONEncoder'>, style={'base_template': 'textarea.html'})
|
||||
""")
|
||||
self.assertEqual(repr(TestSerializer()), expected)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user