mirror of https://github.com/django/django.git
Fixed #15091 -- Allowed passing custom encoder to JSON serializer.
This commit is contained in:
parent
6bf7964023
commit
c1b6f554e4
|
@ -37,6 +37,7 @@ class Serializer(PythonSerializer):
|
||||||
if self.options.get('indent'):
|
if self.options.get('indent'):
|
||||||
# Prevent trailing spaces
|
# Prevent trailing spaces
|
||||||
self.json_kwargs['separators'] = (',', ': ')
|
self.json_kwargs['separators'] = (',', ': ')
|
||||||
|
self.json_kwargs.setdefault('cls', DjangoJSONEncoder)
|
||||||
|
|
||||||
def start_serialization(self):
|
def start_serialization(self):
|
||||||
self._init_options()
|
self._init_options()
|
||||||
|
@ -58,8 +59,7 @@ class Serializer(PythonSerializer):
|
||||||
self.stream.write(" ")
|
self.stream.write(" ")
|
||||||
if indent:
|
if indent:
|
||||||
self.stream.write("\n")
|
self.stream.write("\n")
|
||||||
json.dump(self.get_dump_object(obj), self.stream,
|
json.dump(self.get_dump_object(obj), self.stream, **self.json_kwargs)
|
||||||
cls=DjangoJSONEncoder, **self.json_kwargs)
|
|
||||||
self._current = None
|
self._current = None
|
||||||
|
|
||||||
def getvalue(self):
|
def getvalue(self):
|
||||||
|
|
|
@ -206,6 +206,10 @@ Serialization
|
||||||
* The new ``django.core.serializers.base.Serializer.stream_class`` attribute
|
* The new ``django.core.serializers.base.Serializer.stream_class`` attribute
|
||||||
allows subclasses to customize the default stream.
|
allows subclasses to customize the default stream.
|
||||||
|
|
||||||
|
* The encoder used by the :ref:`JSON serializer <serialization-formats-json>`
|
||||||
|
can now be customized by passing a ``cls`` keyword argument to the
|
||||||
|
``serializers.serialize()`` function.
|
||||||
|
|
||||||
Signals
|
Signals
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,17 @@ work::
|
||||||
return force_text(obj)
|
return force_text(obj)
|
||||||
return super(LazyEncoder, self).default(obj)
|
return super(LazyEncoder, self).default(obj)
|
||||||
|
|
||||||
|
You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()``
|
||||||
|
function::
|
||||||
|
|
||||||
|
from django.core.serializers import serialize
|
||||||
|
|
||||||
|
serialize('json', SomeModel.objects.all(), cls=LazyEncoder)
|
||||||
|
|
||||||
|
.. versionchanged:: 1.11
|
||||||
|
|
||||||
|
The ability to use a custom encoder using ``cls=...`` was added.
|
||||||
|
|
||||||
Also note that GeoDjango provides a :doc:`customized GeoJSON serializer
|
Also note that GeoDjango provides a :doc:`customized GeoJSON serializer
|
||||||
</ref/contrib/gis/serializers>`.
|
</ref/contrib/gis/serializers>`.
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import decimal
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
from django.core.serializers.base import DeserializationError
|
from django.core.serializers.base import DeserializationError
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
|
from django.db import models
|
||||||
from django.test import SimpleTestCase, TestCase, TransactionTestCase
|
from django.test import SimpleTestCase, TestCase, TransactionTestCase
|
||||||
|
from django.test.utils import isolate_apps
|
||||||
from django.utils.translation import override, ugettext_lazy
|
from django.utils.translation import override, ugettext_lazy
|
||||||
|
|
||||||
from .models import Score
|
from .models import Score
|
||||||
|
@ -80,6 +83,23 @@ class JsonSerializerTestCase(SerializersTestBase, TestCase):
|
||||||
if re.search(r'.+,\s*$', line):
|
if re.search(r'.+,\s*$', line):
|
||||||
self.assertEqual(line, line.rstrip())
|
self.assertEqual(line, line.rstrip())
|
||||||
|
|
||||||
|
@isolate_apps('serializers')
|
||||||
|
def test_custom_encoder(self):
|
||||||
|
class ScoreDecimal(models.Model):
|
||||||
|
score = models.DecimalField()
|
||||||
|
|
||||||
|
class CustomJSONEncoder(json.JSONEncoder):
|
||||||
|
def default(self, o):
|
||||||
|
if isinstance(o, decimal.Decimal):
|
||||||
|
return str(o)
|
||||||
|
return super(CustomJSONEncoder, self).default(o)
|
||||||
|
|
||||||
|
s = serializers.json.Serializer()
|
||||||
|
json_data = s.serialize(
|
||||||
|
[ScoreDecimal(score=decimal.Decimal(1.0))], cls=CustomJSONEncoder
|
||||||
|
)
|
||||||
|
self.assertIn('"fields": {"score": "1"}', json_data)
|
||||||
|
|
||||||
def test_json_deserializer_exception(self):
|
def test_json_deserializer_exception(self):
|
||||||
with self.assertRaises(DeserializationError):
|
with self.assertRaises(DeserializationError):
|
||||||
for obj in serializers.deserialize("json", """[{"pk":1}"""):
|
for obj in serializers.deserialize("json", """[{"pk":1}"""):
|
||||||
|
|
Loading…
Reference in New Issue