Kaydet (Commit) c1b6f554 authored tarafından Berker Peksag's avatar Berker Peksag Kaydeden (comit) Tim Graham

Fixed #15091 -- Allowed passing custom encoder to JSON serializer.

üst 6bf79640
...@@ -37,6 +37,7 @@ class Serializer(PythonSerializer): ...@@ -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): ...@@ -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 ...@@ -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:: ...@@ -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>`.
......
# -*- 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): ...@@ -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}"""):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment