如何正确使用django/jinja2模板过滤器'escape'和'linebreaks'?

4 投票
3 回答
5932 浏览
提问于 2025-04-16 11:15

我现在正在尝试使用django模板过滤器来转义一个变量,具体如下。 我使用的是jinja2模板引擎,而不是django的主要模板引擎。

{{ my_variable|escape|linebreaks }}

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

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

理想情况下,

<br />

不应该被转义,因为它是通过“linebreaks”过滤器添加的。原始字符串中没有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>

有没有人知道我在应用模板过滤器时是否做错了什么,或者能否给我指个方向?

谢谢。

3 个回答

0

为了说明情况,我当时使用的是Django自带的模板引擎,它有一个叫做 linebreaksbr 的功能(还有一个叫 linesbreaks 的功能)。所以我用同样的功能定义了一个自定义的过滤器:

from django.template.defaultfilters import linebreaksbr, linebreaks

env = Environment(
    # Your config...
)
env.filters["linebreaks"] = linebreaks
env.filters["linebreaksbr"] = linebreaksbr
5

你在使用 Django 的 linebreaks 过滤器在 jinja2 模板中吗?如果是这样的话,我猜 Django 标记字符串为安全的方式可能和 jinja2 不兼容,所以如果开启了自动转义,Django 添加的标签可能会被转义。

那如果你在最后加上 jinja2 的 safe 过滤器呢?

{{ my_variable|escape|linebreaks|safe }}

另外,jinja2 文档中有一个关于自定义过滤器的例子,看起来和 Django 的 linebreaks 有点相似。你可以查看这个链接了解更多: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
2

我真是傻,看来我可以用:

{{ my_variable|forceescape|linebreaks }}

来强制让'escape'这个过滤器先执行。默认情况下,'escape'这个过滤器总是在其他所有过滤器执行完后才会应用,不管它的位置在哪里。所以,使用force_escape是另一个非常简单的选择。

撰写回答