Last week I started a post series exploring the django.utils
module. In this second part I will be focusing more
on the html
module.
HTML
Module: django.utils.html
escape
Returns the given text with ampersands, quotes and angle brackets encoded for use in HTML.
from django.utils.html import escape
escape("<strong style='font-size: 12px'>escaped html</strong>")
'<strong style='font-size: 12px'>escaped html</strong>'
It will cause already escaped strings to be escaped again:
escaped_html = escape("<strong>escaped html</strong>")
# '<strong>escaped html</strong>'
escape(escaped_html)
# '&lt;strong&gt;escaped html&lt;/strong&gt;'
If this is a concern, use conditional_escape()
instead.
conditional_escape
escaped_html = conditional_escape("<strong>escaped html</strong>")
# '<strong>escaped html</strong>'
conditional_escape(escaped_html)
# '<strong>escaped html</strong>'
format_html
This function is similar to str.format, but it will conditional escape all the arguments. Prefer to use it to build small HTML fragments instead of str.format or string interpolation, as it is safer.
from django.utils.html import format_html
format_html('<div class="alert {}">{}</>', 'warning', 'Watch out!')
'<div class="alert warning">Watch out!</>'
Safely format HTML fragments:
format_html('<div class="alert {}">{}</>', '<script>alert(1);</script>', 'Watch out!')
'<div class="alert <script>alert(1);</script>">Watch out!</>'
format_html_join
A wrapper of format_html, for the common case of a group of arguments that need to be formatted using the same format string.
format_html_join('\n', '<p>{}</p>', ['a', 'b', 'c'])
<p>a</p>\n<p>b</p>\n<p>c</p>
Another example:
data = [
['success', 'Success message'],
['warning', 'Watch out!'],
['danger', 'Danger!!'],
]
format_html_join('\n', '<div class="alert {0}">{1}</div>', data)
<div class="alert success">Success message</div>\n
<div class="alert warning">Watch out!</div>\n
<div class="alert danger">Danger!!</div>
Yet another example:
format_html_join('\n', '<tr><td>{0}</td><td>{1}</td></tr>', ((u.first_name, u.last_name)
for u in users))
<tr><td>Vitor</td><td>Freitas</td></tr>\n
<tr><td>John</td><td>Duo</td></tr>\n
<tr><td>Peter</td><td>Croke</td></tr>\n
<tr><td>Elektra</td><td>Moore</td></tr>
linebreaks
from django.utils.html import linebreaks
linebreaks('convert\ninto html paragraphs\ntest')
<p>convert<br />into html paragraphs<br />test</p>