如何正确应用 django/jinja2 模板过滤器“转义”和“换行符”?

Posted

技术标签:

【中文标题】如何正确应用 django/jinja2 模板过滤器“转义”和“换行符”?【英文标题】:How to apply django/jinja2 template filters 'escape' and 'linebreaks' correctly? 【发布时间】:2011-06-21 13:12:51 【问题描述】:

我目前正在尝试使用 django 模板过滤器来转义变量,如下所示。 我使用 jinja2 模板引擎,而不仅仅是 django 的主要模板引擎

 my_variable|escape|linebreaks 

带有换行符的字符串的输出如下:

Lorem ipsum <br /> dolor sit amet <br />rg srg
gs rgsr rsg serg<br />r srg

理想情况下

<br />

不应该被转义,因为它是由“换行符”过滤器添加的。没有带有原始字符串的 html 标记。

我试过了:

 my_variable|linebreaks|escape 

但是,结果更糟:

<p>Lorem ipsum <br /> dolor sit amet <br />rg srg</p>
<p>gs rgsr rsg serg<br />r srg</p>

有谁知道我在应用模板过滤器时是否做错了什么,和/或能否为我指明正确的方向?

谢谢。

【问题讨论】:

【参考方案1】:

所以你在 jinja2 模板中使用了 django 的 linebreaks 过滤器?在这种情况下,我会假设 django 标记字符串安全的方式可能与 jinja2 不兼容,因此转义了 django 添加的标签(如果 autoescape 处于活动状态)。

如果您将 jinja2 的安全过滤器添加到末尾会怎样?

 my_variable|escape|linebreaks|safe 

否则,jinja2 文档中有一个自定义过滤器的示例,它似乎类似于 django 的换行符。 http://jinja.pocoo.org/docs/api/#custom-filters

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r|\n)2,')

@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
                      for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

【讨论】:

感谢您将我指向 jinja2 自定义过滤器。虽然这是一个更复杂的解决方案,但它帮助我找出了一个相关的问题,即实现自定义过滤器来为 urlize 链接执行 target="_blank"。谢谢! @VKen 你介意分享 target="_blank" urlize 代码吗?我一直在寻找实现该功能的方法。【参考方案2】:

我傻了,看来我可以用:

 my_variable|forceescape|linebreaks 

强制首先应用“转义”过滤器。 默认情况下,'escape' 仅适用于所有其他过滤器的末尾,而不管位置如何,因此 force_escape 是另一个最简单的替代方案。

【讨论】:

我最终不得不做 my_variable|escape|linebreaks|safe (正如@Reiner 建议的那样)只是为我做forceescape 双重转义的事情。

以上是关于如何正确应用 django/jinja2 模板过滤器“转义”和“换行符”?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中过滤 Queryset 并设计正确的 urls.py 和模板

如何获取相关项目的列表并在 Django 中应用模板过滤器

如何有条件地在 Django 中应用模板过滤器?

Django模板如何对简单标签返回的结果应用过滤器

Python / Django / Jinja2:如何用另一个变量的值扩展变量名(例如在 for 循环中)?

Mako