Fixed #33779 -- Allowed customizing encoder class in django.utils.html.json_script().
This commit is contained in:
parent
0ee03a439b
commit
72e41a0df6
|
@ -59,7 +59,7 @@ _json_script_escapes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def json_script(value, element_id=None):
|
def json_script(value, element_id=None, encoder=None):
|
||||||
"""
|
"""
|
||||||
Escape all the HTML/XML special characters with their unicode escapes, so
|
Escape all the HTML/XML special characters with their unicode escapes, so
|
||||||
value is safe to be output anywhere except for inside a tag attribute. Wrap
|
value is safe to be output anywhere except for inside a tag attribute. Wrap
|
||||||
|
@ -67,7 +67,9 @@ def json_script(value, element_id=None):
|
||||||
"""
|
"""
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
|
|
||||||
json_str = json.dumps(value, cls=DjangoJSONEncoder).translate(_json_script_escapes)
|
json_str = json.dumps(value, cls=encoder or DjangoJSONEncoder).translate(
|
||||||
|
_json_script_escapes
|
||||||
|
)
|
||||||
if element_id:
|
if element_id:
|
||||||
template = '<script id="{}" type="application/json">{}</script>'
|
template = '<script id="{}" type="application/json">{}</script>'
|
||||||
args = (element_id, mark_safe(json_str))
|
args = (element_id, mark_safe(json_str))
|
||||||
|
|
|
@ -655,7 +655,7 @@ escaping HTML.
|
||||||
((u.first_name, u.last_name) for u in users)
|
((u.first_name, u.last_name) for u in users)
|
||||||
)
|
)
|
||||||
|
|
||||||
.. function:: json_script(value, element_id=None)
|
.. function:: json_script(value, element_id=None, encoder=None)
|
||||||
|
|
||||||
Escapes all HTML/XML special characters with their Unicode escapes, so
|
Escapes all HTML/XML special characters with their Unicode escapes, so
|
||||||
value is safe for use with JavaScript. Also wraps the escaped JSON in a
|
value is safe for use with JavaScript. Also wraps the escaped JSON in a
|
||||||
|
@ -665,10 +665,19 @@ escaping HTML.
|
||||||
>> json_script({"hello": "world"}, element_id="hello-data")
|
>> json_script({"hello": "world"}, element_id="hello-data")
|
||||||
'<script id="hello-data" type="application/json">{"hello": "world"}</script>'
|
'<script id="hello-data" type="application/json">{"hello": "world"}</script>'
|
||||||
|
|
||||||
|
The ``encoder``, which defaults to
|
||||||
|
:class:`django.core.serializers.json.DjangoJSONEncoder`, will be used to
|
||||||
|
serialize the data. See :ref:`JSON serialization
|
||||||
|
<serialization-formats-json>` for more details about this serializer.
|
||||||
|
|
||||||
.. versionchanged:: 4.1
|
.. versionchanged:: 4.1
|
||||||
|
|
||||||
In older versions, the ``element_id`` argument was required.
|
In older versions, the ``element_id`` argument was required.
|
||||||
|
|
||||||
|
.. versionchanged:: 4.2
|
||||||
|
|
||||||
|
The ``encoder`` argument was added.
|
||||||
|
|
||||||
.. function:: strip_tags(value)
|
.. function:: strip_tags(value)
|
||||||
|
|
||||||
Tries to remove anything that looks like an HTML tag from the string, that
|
Tries to remove anything that looks like an HTML tag from the string, that
|
||||||
|
|
|
@ -214,7 +214,8 @@ URLs
|
||||||
Utilities
|
Utilities
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* The new ``encoder`` parameter for :meth:`django.utils.html.json_script`
|
||||||
|
function allows customizing a JSON encoder class.
|
||||||
|
|
||||||
Validators
|
Validators
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils.functional import lazystr
|
from django.utils.functional import lazystr
|
||||||
from django.utils.html import (
|
from django.utils.html import (
|
||||||
|
@ -211,6 +212,16 @@ class TestUtilsHtml(SimpleTestCase):
|
||||||
with self.subTest(arg=arg):
|
with self.subTest(arg=arg):
|
||||||
self.assertEqual(json_script(arg, "test_id"), expected)
|
self.assertEqual(json_script(arg, "test_id"), expected)
|
||||||
|
|
||||||
|
def test_json_script_custom_encoder(self):
|
||||||
|
class CustomDjangoJSONEncoder(DjangoJSONEncoder):
|
||||||
|
def encode(self, o):
|
||||||
|
return '{"hello": "world"}'
|
||||||
|
|
||||||
|
self.assertHTMLEqual(
|
||||||
|
json_script({}, encoder=CustomDjangoJSONEncoder),
|
||||||
|
'<script type="application/json">{"hello": "world"}</script>',
|
||||||
|
)
|
||||||
|
|
||||||
def test_json_script_without_id(self):
|
def test_json_script_without_id(self):
|
||||||
self.assertHTMLEqual(
|
self.assertHTMLEqual(
|
||||||
json_script({"key": "value"}),
|
json_script({"key": "value"}),
|
||||||
|
|
Loading…
Reference in New Issue