summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2015-09-26 20:15:26 +0200
committerClaude Paroz <claude@2xlibre.net>2015-09-27 22:37:27 +0200
commitb7ade645290ecf45530fe7211f8f759fc9cf9971 (patch)
treef28449efe250495afa3b11aa8fce01c85b1df29e
parent87630bc3042da106b29fb1307bb77426f80dcf84 (diff)
Fixed #25468 -- Made DjangoJSONEncoder lazy string aware
Thanks Stavros Korokithakis for the report and Tim Graham for the review.
-rw-r--r--django/core/serializers/json.py3
-rw-r--r--docs/releases/1.10.txt6
-rw-r--r--docs/topics/serialization.txt7
-rw-r--r--tests/serializers/test_json.py17
4 files changed, 28 insertions, 5 deletions
diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py
index e023997681..4c963b0b79 100644
--- a/django/core/serializers/json.py
+++ b/django/core/serializers/json.py
@@ -16,6 +16,7 @@ from django.core.serializers.python import (
Deserializer as PythonDeserializer, Serializer as PythonSerializer,
)
from django.utils import six
+from django.utils.functional import Promise
from django.utils.timezone import is_aware
@@ -111,6 +112,8 @@ class DjangoJSONEncoder(json.JSONEncoder):
return str(o)
elif isinstance(o, uuid.UUID):
return str(o)
+ elif isinstance(o, Promise):
+ return six.text_type(o)
else:
return super(DjangoJSONEncoder, self).default(o)
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index bd32f874d9..66d3828087 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -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
^^^^^^^
diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt
index e34553699d..2221463210 100644
--- a/docs/topics/serialization.txt
+++ b/docs/topics/serialization.txt
@@ -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`_.
Be aware that not all Django output can be passed unmodified to :mod:`json`.
-In particular, :ref:`lazy translation objects <lazy-translations>` need a
-`special encoder`_ written for them. Something like this will work::
+For example, if you have some custom type in an object to be serialized, you'll
+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.core.serializers.json import DjangoJSONEncoder
class LazyEncoder(DjangoJSONEncoder):
def default(self, obj):
- if isinstance(obj, Promise):
+ if isinstance(obj, YourCustomType):
return force_text(obj)
return super(LazyEncoder, self).default(obj)
diff --git a/tests/serializers/test_json.py b/tests/serializers/test_json.py
index 4239dcef8d..d8d445d1f9 100644
--- a/tests/serializers/test_json.py
+++ b/tests/serializers/test_json.py
@@ -6,7 +6,9 @@ import re
from django.core import serializers
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 .tests import SerializersTestBase, SerializersTransactionTestBase
@@ -271,3 +273,16 @@ class JsonSerializerTransactionTestCase(SerializersTransactionTestBase, Transact
"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"}'
+ )