Kaydet (Commit) b7ade645 authored tarafından Claude Paroz's avatar Claude Paroz

Fixed #25468 -- Made DjangoJSONEncoder lazy string aware

Thanks Stavros Korokithakis for the report and Tim Graham for the
review.
üst 87630bc3
...@@ -16,6 +16,7 @@ from django.core.serializers.python import ( ...@@ -16,6 +16,7 @@ from django.core.serializers.python import (
Deserializer as PythonDeserializer, Serializer as PythonSerializer, Deserializer as PythonDeserializer, Serializer as PythonSerializer,
) )
from django.utils import six from django.utils import six
from django.utils.functional import Promise
from django.utils.timezone import is_aware from django.utils.timezone import is_aware
...@@ -111,6 +112,8 @@ class DjangoJSONEncoder(json.JSONEncoder): ...@@ -111,6 +112,8 @@ class DjangoJSONEncoder(json.JSONEncoder):
return str(o) return str(o)
elif isinstance(o, uuid.UUID): elif isinstance(o, uuid.UUID):
return str(o) return str(o)
elif isinstance(o, Promise):
return six.text_type(o)
else: else:
return super(DjangoJSONEncoder, self).default(o) return super(DjangoJSONEncoder, self).default(o)
......
...@@ -162,6 +162,12 @@ Requests and Responses ...@@ -162,6 +162,12 @@ Requests and Responses
* ... * ...
Serialization
^^^^^^^^^^^^^
* The ``django.core.serializers.json.DjangoJSONEncoder`` now knows how to
serialize lazy strings, typically used for translatable content.
Signals Signals
^^^^^^^ ^^^^^^^
......
...@@ -256,16 +256,15 @@ Date and datetime related types are treated in a special way by the JSON ...@@ -256,16 +256,15 @@ Date and datetime related types are treated in a special way by the JSON
serializer to make the format compatible with `ECMA-262`_. serializer to make the format compatible with `ECMA-262`_.
Be aware that not all Django output can be passed unmodified to :mod:`json`. Be aware that not all Django output can be passed unmodified to :mod:`json`.
In particular, :ref:`lazy translation objects <lazy-translations>` need a For example, if you have some custom type in an object to be serialized, you'll
`special encoder`_ written for them. Something like this will work:: have to write a `special encoder`_ for it. Something like this will work::
from django.utils.functional import Promise
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
class LazyEncoder(DjangoJSONEncoder): class LazyEncoder(DjangoJSONEncoder):
def default(self, obj): def default(self, obj):
if isinstance(obj, Promise): if isinstance(obj, YourCustomType):
return force_text(obj) return force_text(obj)
return super(LazyEncoder, self).default(obj) return super(LazyEncoder, self).default(obj)
......
...@@ -6,7 +6,9 @@ import re ...@@ -6,7 +6,9 @@ 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.test import TestCase, TransactionTestCase from django.core.serializers.json import DjangoJSONEncoder
from django.test import SimpleTestCase, TestCase, TransactionTestCase
from django.utils.translation import override, ugettext_lazy
from .models import Score from .models import Score
from .tests import SerializersTestBase, SerializersTransactionTestBase from .tests import SerializersTestBase, SerializersTransactionTestBase
...@@ -271,3 +273,16 @@ class JsonSerializerTransactionTestCase(SerializersTransactionTestBase, Transact ...@@ -271,3 +273,16 @@ class JsonSerializerTransactionTestCase(SerializersTransactionTestBase, Transact
"name": "Agnes" "name": "Agnes"
} }
}]""" }]"""
class DjangoJSONEncoderTests(SimpleTestCase):
def test_lazy_string_encoding(self):
self.assertEqual(
json.dumps({'lang': ugettext_lazy("French")}, cls=DjangoJSONEncoder),
'{"lang": "French"}'
)
with override('fr'):
self.assertEqual(
json.dumps({'lang': ugettext_lazy("French")}, cls=DjangoJSONEncoder),
'{"lang": "Fran\\u00e7ais"}'
)
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