Python / Django render_to_string outpu отображается как текст с html-сущностями
Я переношу приложение python / Django с: Django==1.5.1 python версии 2.6.6
to
Django==3.2 python версии 3.6.8
Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть раздел кода, который преобразует в строку определенный HTML-шаблон, а затем добавляет его в список для вывода в другом месте.
Фактический код, который производит этот HTML, следующий:
class AccountAdmin(SmarterModelAdmin):
list_display = ('username', 'files_url', 'teamMembers', 'roleMemberships', 'safetyLimit', 'admin_quota', 'manager', 'enabled', 'path')
list_filter = ['enabled', 'manager', 'accountType']
search_fields = ['username']
inlines = [RolesInline]
valid_lookups = (
'members__member__username',
'teams__role__username',
)
roles = Account.objects.filter(teams__member=account).order_by('username')
roleList = []
for role in roles:
link = '/admin/files/account/?teams__role__username=' + role.username
# mylink = '<a href="{myurl}">'+role.username+'</a>'
# linkText = format_html(mylink,myurl=link)
linkText = render_to_string('common/contact.html', context={'URL': link, 'contact': role})
roleList.append(linkText)
return ', '.join(roleList)
roleMemberships.short_description='Roles'
roleMemberships.allow_tags=True```
Я добавил logging.warn для проверки того, что выходит из render_to_string, и это прямой HTML.
Закомментированные строки - это то, что я пробовал, что устранило аналогичную проблему.
common/contact.html это:
<a
href="{{ URL }}"
{% if not contact.enabled %}
style="text-decoration:line-through;"
{% endif %}
>{{ contact.username }}</a>
Однако, при окончательном рендеринге получается вот так:
abaumann, abaumann, который при запуске через браузер выглядит следующим образом:
Я не смог найти ничего, что ссылалось бы на эту конкретную проблему. У меня все остальное работает в разделе администратора приложения django, и я в растерянности, почему оно не отображается так, как ожидалось.
Пожалуйста, дайте мне знать, если есть что-то еще, что вам нужно увидеть.
Я был на правильном пути, просто возникла проблема с реализацией.
Бэкенд Django пытается сделать все безопасным. Поэтому сгенерированный HTML из моего шаблона не считался безопасным. Поэтому использование функции mark_safe() было ключевым моментом. Но где ее разместить - вот в чем проблема.
Когда переменная, содержащая HTML, изменяется ЛЮБЫМ способом, флаг "safe" снимается, и переменная проходит через кодировку, чтобы преобразовать любой HTML в текст.
Итак, исправление происходит в этой строке:
return ', '.join(roleList)
измените его на:
return mark_safe(', '.join(roleList))
Моя ошибка заключалась в том, что я поместил mark_safe в переменную linkText либо в момент установки переменной, либо когда она была добавлена в roleList.