Подтвердить что ты не робот

Как я могу выводить HTML в сообщении в новой структуре сообщений Django?

Я пытаюсь отобразить немного html в сообщении, которое отображается через новую структуру сообщений Django. В частности, я делаю это с помощью метода ModelAdmin.message_user, который представляет собой лишь тонкую оболочку сообщений():

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)

Все, что я пробовал до сих пор, похоже, отображает экранированный HTML.

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

Не работает и не работает:

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

Отображение кода шаблона в шаблоне admin base.html довольно просто:

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

Поэтому я не совсем уверен, что я делаю неправильно.

Мысли или руководство получили высокую оценку, спасибо!

4b9b3361

Ответ 1

Другой вариант - использовать extra_tags keyword arg, чтобы указать, что сообщение безопасно. Например,

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

затем используйте шаблонную логику для использования безопасного фильтра

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

Ответ 2

Как указано в следующем билете Django, он должен работать, если вы используете mark_safe() в сочетании с бэкэнд SessionStorage: https://code.djangoproject.com/ticket/14976#comment:9

Ответ 3

Вы пробовали {{ message | safe }}?

В шаблоне шаблона шаблона Django всегда сбрасываются, если вы не указали их как безопасные с фильтром safe. Это значение по умолчанию делает даже невредимым защиту от инъекции.

Я не уверен, как это взаимодействует с mark_safe, но, возможно, что-то произошло между ними, что снова стало небезопасным.

Ответ 4

Это сработало для меня (Джанго 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>'))

Ответ 5

Я искал способ использовать unescaped HTML в списке admin. Не уверен, что это относится к структуре сообщений, но использование allow_tags, как описано здесь, помогло мне.

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

Ответ 6

Весь смысл системы шаблонов состоит в том, чтобы иметь дело со строками и данными, подобными этим.

В то время как каждый другой ответ указывает на то, что вы должны пометить вашу созданную строку как безопасную, я бы пошел еще дальше и сказал бы вам никогда не использовать HTML в вашем коде - всегда используйте шаблон.

Система шаблонов гарантирует, что вещи должным образом экранированы, так что вам не нужно об этом беспокоиться, и программисту гораздо сложнее попасть в ситуацию, когда они создают строку HTML из набора if и пользовательские данные.

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,
        ),
    )

Ответ 7

Вы можете использовать format_html. Это относится к экранированию всех аргументов.

Например, если мы можем связать детали mymodel с помощью атрибута, называемого 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)

Этот ответ основан на fooobar.com/info/430515/...