假设我们有这样的信息:
messages.add_message(request, messages.SUCCESS,
_('Document <a href="%(url)s">%(doc_type_name)s %(name)s (%(fname)s)</a> created.') % {
'doc_type_name': conditional_escape(document.doc_type.name),
'name': conditional_escape(document.title),
'fname': conditional_escape(document.name),
'url': document.get_absolute_url()
})
此处仅当我们使用{{ message|safe }}
显示消息时才会有效,但我们不希望这样,因为如果%(name)
中有一些代码,它也会被执行。
如果我使用:
messages.add_message(request, messages.SUCCESS,
mark_safe(_('Document <a href="%(url)s">%(doc_type_name)s %(name)s (%(fname)s)</a> created.') % {
'doc_type_name': conditional_escape(document.doc_type.name),
'name': conditional_escape(document.title),
'fname': conditional_escape(document.name),
'url': document.get_absolute_url()
}))
mark_safe
不起作用。
我在那里阅读了一个解决方案:https://stackoverflow.com/a/12600388/186202
但这与我需要的相反:
_('Document %s created.') % mark_safe('')
一旦它通过ugettext function
,它就不再安全了。
我该怎么办?
答案 0 :(得分:2)
您正在尝试通过将HTML放在Python代码中来混合视图和逻辑。好吧,有时你只需要做到这一点但事实并非如此。
mark_safe()返回由Django模板专门处理的SafeString对象。如果由ugettext或%评估SafeString,您将再次获得字符串,这是预期的行为。你不能只标记安全的格式化字符串,要么是带有doc名称/标题等的完整输出,要么一切都不安全。即,它不会以这种方式工作。
您可以将HTML放入模板并使用render_to_string(),这可能是最佳选择。
用户是否设置了文档标题,名称和doc_type.name?如果没有,您可以跳过mark_safe并使用文档属性中的HTML作为功能文档。
答案 1 :(得分:0)
以前的回答是正确的:你应该尽量避免混合使用python和html。
解决您的问题:
from django.utils import six # Python 3 compatibility
from django.utils.functional import lazy
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
mark_safe_lazy = lazy(mark_safe, six.text_type)
然后:
lazy_string = mark_safe_lazy(_("<p>My <strong>string!</strong></p>"))
在django文档中找到: https://docs.djangoproject.com/en/1.9/topics/i18n/translation/#s-other-uses-of-lazy-in-delayed-translations