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'):
|
||||
# Prevent trailing spaces
|
||||
self.json_kwargs['separators'] = (',', ': ')
|
||||
self.json_kwargs.setdefault('cls', DjangoJSONEncoder)
|
||||
|
||||
def start_serialization(self):
|
||||
self._init_options()
|
||||
|
@ -58,8 +59,7 @@ class Serializer(PythonSerializer):
|
|||
self.stream.write(" ")
|
||||
if indent:
|
||||
self.stream.write("\n")
|
||||
json.dump(self.get_dump_object(obj), self.stream,
|
||||
cls=DjangoJSONEncoder, **self.json_kwargs)
|
||||
json.dump(self.get_dump_object(obj), self.stream, **self.json_kwargs)
|
||||
self._current = None
|
||||
|
||||
def getvalue(self):
|
||||
|
|
|
@ -206,6 +206,10 @@ Serialization
|
|||
* The new ``django.core.serializers.base.Serializer.stream_class`` attribute
|
||||
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
|
||||
~~~~~~~
|
||||
|
||||
|
|
|
@ -265,6 +265,17 @@ work::
|
|||
return force_text(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
|
||||
</ref/contrib/gis/serializers>`.
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import decimal
|
||||
import json
|
||||
import re
|
||||
|
||||
from django.core import serializers
|
||||
from django.core.serializers.base import DeserializationError
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase, TestCase, TransactionTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
from django.utils.translation import override, ugettext_lazy
|
||||
|
||||
from .models import Score
|
||||
|
@ -80,6 +83,23 @@ class JsonSerializerTestCase(SerializersTestBase, TestCase):
|
|||
if re.search(r'.+,\s*$', line):
|
||||
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):
|
||||
with self.assertRaises(DeserializationError):
|
||||
for obj in serializers.deserialize("json", """[{"pk":1}"""):
|
||||
|
|
Loading…
Reference in New Issue