How can I output HTML in a message in a new Django message structure?

I am trying to display a bit of html in a message that displays through the new Django message structure. In particular, I do this using the ModelAdmin.message_user method, which is just a thin shell of messages ():

def message_user(self, request, message): """ Send a message to the user. The default implementation posts a message using the django.contrib.messages backend. """ messages.info(request, message) 

Everything I've tried so far seems to display escaped HTML.

 self.message_user(request, "<a href=\"http://www.google.com\">Here google!</a>") 

Doesn't work and doesn't work:

 from django.utils.safestring import mark_safe ... self.message_user(request, mark_safe("<a href=\"http://www.google.com\">Here google!</a>")) 

Displaying the template code in the admin template base.html is pretty simple:

  {% if messages %} <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul> {% endif %} 

Therefore, I am not entirely sure what I am doing wrong.

Thoughts or guidance were greatly appreciated, thanks!

+62
django
Jan 12 '10 at 23:30
source share
7 answers

Another option is to use extra_tags keyword arg to indicate that the message is safe. For example,

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

then use template logic to use a safe filter

 {% for message in messages %} <li class="{{ message.tags }}"> {% if 'safe' in message.tags %}{{ message|safe }}{% else %}{{ message }}{% endif %} </li> {% endfor %} 
+74
Apr 12 2018-12-12T00:
source share

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

+22
Jan 04 2018-12-12T00:
source share

Have you tried {{ message | safe }} {{ message | safe }} ?

In the template template, Django templates are always reset unless you have specified them as safe with the safe filter. This default value even makes injection protection unscathed.

I'm not sure how this interacts with mark_safe, but maybe something happened between them, which again became unsafe.

+16
Jan 12 '10 at 23:33
source share

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>')) 
+6
Apr 04 '18 at 9:50
source share

I was looking for a way to use unescaped HTML in the admin list. Not sure if this relates to the message structure, but using allow_tags as described here helped me.

http://urlencode.blogspot.com/2009/10/neat-django-admin-tricks-part-1.html

0
Jan 14 '10 at 19:20
source share

The whole point of a templating system is to deal with strings and data like this.

While every other answer indicates that you should mark your created string as safe, I would go even further and tell you to never use HTML in your code - always use a template.

The template system ensures that things are properly shielded, so you donโ€™t have to worry about this, and itโ€™s much harder for a programmer to get into a situation where they create an HTML string from an if set and user data.

app/templates/app/fragments/google_link.html :

 <a href="https://www.google.com">Here Google!</a> 

views.py :

 from django.template import loader ... def view(request): messages.info( request, loader.render_to_string( 'app/fragments/google_link.html', {}, request=request, ), ) 
0
Aug 12 '19 at 20:58
source share

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

For example, if we can link the details of mymodel with an attribute called 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 Stack Overflow

0
Sep 26 '19 at 18:33
source share



All Articles