How do I output HTML in a message in the new Django messages framework?

Another option is to use extra_tags keyword arg to indicate that a message is safe. Eg

messages.error(request, 'Here is a <a href="/">link</a>', extra_tags='safe')

then use template logic to use the safe filter

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

As noted in the following Django ticket, it should work if you use mark_safe() in combination with the SessionStorage backend: https://code.djangoproject.com/ticket/14976#comment:9


This worked for me (Django 1.11):

from django.contrib import messages
from django.utils.safestring import mark_safe

messages.info(request, mark_safe('This is link to <a href="http://google.com">http://google.com</a>'))

Have you tried {{ message | safe }}?

In the Django template system template variables are always escaped, unless you specify them as safe with the safe filter. This default makes even the unaware protected against an injection attack.

I'm not sure how that interacts with mark_safe, but perhaps something happened in between that made it unsafe again.


You can use format_html. It applies escaping to all arguments.

For example, if we can link with a 'mymodel' detail using an attribute call 'name':

from django.contrib import messages
from django.utils.html import format_html


message = format_html("{} <a href='{}'>{}</a>",
                      "This is the mymodel", 
                      reverse('myapp:mymodel-detail', args=(mymodel.id,)),
                      mymodel.name)
messages.info(request, message)

This answer is based on https://stackoverflow.com/a/33751717/3816639