0
0
mirror of https://github.com/django/django.git synced 2024-11-21 19:09:18 +01:00

Fixed #35668 -- Added mapping support to format_html_join.

This commit is contained in:
nabil-rady 2024-08-14 00:58:37 +03:00 committed by Sarah Boyce
parent ca1318988c
commit 231c0d8593
4 changed files with 54 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import html
import json
import re
import warnings
from collections.abc import Mapping
from html.parser import HTMLParser
from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit
@ -155,7 +156,12 @@ def format_html_join(sep, format_string, args_generator):
"""
return mark_safe(
conditional_escape(sep).join(
format_html(format_string, *args) for args in args_generator
(
format_html(format_string, **args)
if isinstance(args, Mapping)
else format_html(format_string, *args)
)
for args in args_generator
)
)

View File

@ -699,10 +699,29 @@ escaping HTML.
joined using ``sep``. ``sep`` is also passed through
:func:`conditional_escape`.
``args_generator`` should be an iterator that returns the sequence of
``args`` that will be passed to :func:`format_html`. For example::
``args_generator`` should be an iterator that yields arguments to pass to
:func:`format_html`, either sequences of positional arguments or mappings of
keyword arguments.
format_html_join("\n", "<li>{} {}</li>", ((u.first_name, u.last_name) for u in users))
For example, tuples can be used for positional arguments::
format_html_join(
"\n",
"<li>{} {}</li>",
((u.first_name, u.last_name) for u in users),
)
Or dictionaries can be used for keyword arguments::
format_html_join(
"\n",
'<li data-id="{id}">{id} {title}</li>',
({"id": b.id, "title": b.title} for b in books),
)
.. versionchanged:: 5.2
Support for mappings in ``args_generator`` was added.
.. function:: json_script(value, element_id=None, encoder=None)

View File

@ -267,6 +267,10 @@ Utilities
values. This aligns with the :py:class:`str` addition behavior and allows
``__radd__`` to be used if available.
* :func:`~django.utils.html.format_html_join` now supports taking an iterable
of mappings, passing their contents as keyword arguments to
:func:`~django.utils.html.format_html`.
Validators
~~~~~~~~~~

View File

@ -10,6 +10,7 @@ from django.utils.html import (
escape,
escapejs,
format_html,
format_html_join,
html_safe,
json_script,
linebreaks,
@ -75,6 +76,26 @@ class TestUtilsHtml(SimpleTestCase):
name = "Adam"
self.assertEqual(format_html(f"<i>{name}</i>"), "<i>Adam</i>")
def test_format_html_join_with_positional_arguments(self):
self.assertEqual(
format_html_join(
"\n",
"<li>{}) {}</li>",
[(1, "Emma"), (2, "Matilda")],
),
"<li>1) Emma</li>\n<li>2) Matilda</li>",
)
def test_format_html_join_with_keyword_arguments(self):
self.assertEqual(
format_html_join(
"\n",
"<li>{id}) {text}</li>",
[{"id": 1, "text": "Emma"}, {"id": 2, "text": "Matilda"}],
),
"<li>1) Emma</li>\n<li>2) Matilda</li>",
)
def test_linebreaks(self):
items = (
("para1\n\npara2\r\rpara3", "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"),