Embedding HTML in Django messages

Note, this article was published over 4 years ago and hence the content may be stale. Consume with a pinch of salt.


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.


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):
                     'Here is a <a href="/">link</a>.',

Then use some simple template logic to determine whether to use the safe filter:

    {% for message in messages %}
    <li class="{{ message.tags }}">
        {% if 'safe' in message.tags %}
            {{ message|safe }}
        {% else %}
            {{ message }}
        {% endif %}
    {% endfor %}


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.