diff options
| author | Hrushikesh Vaidya <hrushikeshrv@gmail.com> | 2022-06-23 14:20:20 +0530 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-06-28 10:54:38 +0200 |
| commit | 72e41a0df6db23410135364223eeda83ac2a8b27 (patch) | |
| tree | 4c173f6eae2977140cf30bb1f1c10ab9c623c044 | |
| parent | 0ee03a439b7016c068ab2e0c477d5c84f750a82c (diff) | |
Fixed #33779 -- Allowed customizing encoder class in django.utils.html.json_script().
| -rw-r--r-- | django/utils/html.py | 6 | ||||
| -rw-r--r-- | docs/ref/utils.txt | 11 | ||||
| -rw-r--r-- | docs/releases/4.2.txt | 3 | ||||
| -rw-r--r-- | tests/utils_tests/test_html.py | 11 |
4 files changed, 27 insertions, 4 deletions
diff --git a/django/utils/html.py b/django/utils/html.py index d0bc97be80..007602a14a 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -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 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 - 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: template = '<script id="{}" type="application/json">{}</script>' args = (element_id, mark_safe(json_str)) diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 6b44e81611..d296d2bda1 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -655,7 +655,7 @@ escaping HTML. ((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 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") '<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 In older versions, the ``element_id`` argument was required. + .. versionchanged:: 4.2 + + The ``encoder`` argument was added. + .. function:: strip_tags(value) Tries to remove anything that looks like an HTML tag from the string, that diff --git a/docs/releases/4.2.txt b/docs/releases/4.2.txt index ca1c2a0eaa..649fb797c6 100644 --- a/docs/releases/4.2.txt +++ b/docs/releases/4.2.txt @@ -214,7 +214,8 @@ URLs Utilities ~~~~~~~~~ -* ... +* The new ``encoder`` parameter for :meth:`django.utils.html.json_script` + function allows customizing a JSON encoder class. Validators ~~~~~~~~~~ diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index 22a43fd4cd..b7a7396075 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -1,6 +1,7 @@ import os from datetime import datetime +from django.core.serializers.json import DjangoJSONEncoder from django.test import SimpleTestCase from django.utils.functional import lazystr from django.utils.html import ( @@ -211,6 +212,16 @@ class TestUtilsHtml(SimpleTestCase): with self.subTest(arg=arg): 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): self.assertHTMLEqual( json_script({"key": "value"}), |
