Problem
You want to embed HTML within a message using Django’s messages framework.
This is a reasonably common requirement - for instance, it’s common to want to include a link within the message, perhaps pointing the user towards a sign-in or registration page.
This problem exists as of Django 1.4 but may be solved within the framework in later versions.
Solution
Use the extra_tags
keyword argument
to pass a flag indicating that the message is safe for rendering without
escaping. For example:
from django.contrib import messages
def some_view(request):
...
messages.success(request,
'Here is a <a href="/">link</a>.',
extra_tags='safe')
...
Then use some simple template logic to determine whether to use the safe
filter:
<ul>
{% for message in messages %}
<li class="{{ message.tags }}">
{% if 'safe' in message.tags %}
{{ message|safe }}
{% else %}
{{ message }}
{% endif %}
</li>
{% endfor %}
</ul>
Discussion
It’s tempting to use the safe
filter for all messages but this opens up a XSS
security hole if you are not careful as it’s easy to include user input verbatim
in the message. For instance:
from django.contrib import messages
def some_view(request):
code = request.GET['code']
...
messages.success(request, "'%s' is not valid voucher code" % code)
leads to an XSS hole if the safe
filter is used on all messages as the
contents of request.GET['code']
cannot be trusted. It’s better to explicitly
indicate which messages can be safely rendered without escaping.
Taken from a Stack Overflow answer.