PageView

Subscribe to our YouTube Channel!
[Jul 12, 2021] New Video: How to Use Django Rest Framework Permissions (DRF Tutorial - Part 7)


Exploring Django Utils #2

Exploring Django Utils #2

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>")
'&lt;strong style=&#39;font-size: 12px&#39;&gt;escaped html&lt;/strong&gt;'

It will cause already escaped strings to be escaped again:

escaped_html = escape("<strong>escaped html</strong>")
# '&lt;strong&gt;escaped html&lt;/strong&gt;'

escape(escaped_html)
# '&amp;lt;strong&amp;gt;escaped html&amp;lt;/strong&amp;gt;'

If this is a concern, use conditional_escape() instead.

conditional_escape
escaped_html = conditional_escape("<strong>escaped html</strong>")
# '&lt;strong&gt;escaped html&lt;/strong&gt;'

conditional_escape(escaped_html)
# '&lt;strong&gt;escaped html&lt;/strong&gt;'
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 &lt;script&gt;alert(1);&lt;/script&gt;">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>