如何在新的Django消息框架中输出消息中的HTML?

jsd*_*ton 63 django

我试图在通过新的Django消息框架显示的消息中显示一些html.具体来说,我是通过ModelAdmin.message_user方法做到这一点的,它只是对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)
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试的所有内容似乎都显示了转义的HTML.

self.message_user(request, "<a href=\"http://www.google.com\">Here's google!</a>")
Run Code Online (Sandbox Code Playgroud)

不起作用,也不起作用:

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

admin base.html模板中模板代码的显示非常简单:

    {% if messages %}
    <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
    {% endif %}
Run Code Online (Sandbox Code Playgroud)

所以我不确定我做错了什么.

非常感谢您的想法或指导,谢谢!

Dav*_*tom 76

另一种选择是使用extra_tags关键字arg来指示消息是安全的.例如

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

然后使用模板逻辑来使用安全过滤器

{% for message in messages %}
    <li class="{{ message.tags }}">
    {% if 'safe' in message.tags %}{{ message|safe }}{% else %}{{ message }}{% endif %}
    </li>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

  • 如果您还使用bootstrap,请小心使用extra_tags.你会在任何地方看到较旧的建议使用alert - {{message.tags}},但如果你使用extra_tags,这将会中断,因为你会获得警报安全,而不是警报 - 成功.作为解决方案,您可以使用alert - {{message.level_tag}}代替. (7认同)
  • 谢谢你的提示.我认为这是这里提到的最简单但不引人注目且最安全的方法.您可以控制哪个消息标记为安全,而不是盲目地全局应用`{{message | safe}}`. (3认同)
  • @Walkman:如果该消息包含任何不受信任的内容,则不会.像从请求中取出的任何东西; 这是一个XSS漏洞. (3认同)

小智 22

如下面的Django票证所示,如果将mark_safe()与SessionStorage后端结合使用,它应该可以工作:https://code.djangoproject.com/ticket/14976#comment:9

  • 谢谢!一旦我将`MESSAGE_STORAGE ='django.contrib.messages.storage.session.SessionStorage'添加到我的`settings.py`,使用普通的旧mark_safe()就可以了. (3认同)

Dan*_*rts 16

你试过{{ message | safe }}吗?

在Django模板系统中,模板变量总是被转义,除非您使用safe过滤器将它们指定为安全.此默认设置甚至可以防止注意攻击.

我不确定它是如何与mark_safe交互的,但也许在它之间发生了一些让它再次变得不安全的事情.

  • -1. 当有来自用户的任何内容时,这将打开 XSS。例如,“URL 'blaablaa' 无效”,这种情况并不少见。 (2认同)

neg*_*gas 7

您可以使用format_html。它适用于所有参数的转义。

例如,如果我们可以使用属性调用“name”链接到“mymodel”详细信息:

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)
Run Code Online (Sandbox Code Playgroud)

这个答案基于/sf/answers/2362620221/


val*_*lex 6

这对我有用(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>'))
Run Code Online (Sandbox Code Playgroud)

  • 也适用于 Django 版本 3.1.4 (6认同)
  • 谢谢!也适用于 bootstrap_messages! (3认同)
  • 这比所选答案更好,因为添加到标签会破坏使用 css Bootstrap 类 (2认同)