mirror of https://github.com/django/django.git
Fixed #25468 -- Made DjangoJSONEncoder lazy string aware
Thanks Stavros Korokithakis for the report and Tim Graham for the review.
This commit is contained in:
parent
87630bc304
commit
b7ade64529
|
@ -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):
|
||||||
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
|
||||||
|
|
||||||
* ...
|
* ...
|
||||||
|
|
||||||
|
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
"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"}'
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue