Jinja2变量(字符串)被{{分隔符}}包围时不被打印

0 投票
1 回答
989 浏览
提问于 2025-04-18 08:20

我在使用jinja2的时候写了一个宏,之前一直运行得很好,直到我尝试传递一个看起来像这样 /test/{{ vehicle.id }} 的字符串给它。结果在页面上显示的字符串变成了 /test/

这个字符串是从数据库里来的,所以我有点搞不清楚发生了什么。感觉就像jinja在尝试解析这个字符串并替换里面的值(其实这正是我想要的),但它失败了,反而把表达式给去掉了。我还尝试把vehicle这个字典传给宏,看看这样是否能“正常工作”,但结果还是不行。我以为如果我能在上下文中使用 vehicle,那么就会轻松搞定。

这里有一些简单的示例代码:

# Assume db_values.url is set to '/test/{{ vehicle.id }}'
{% macro banner(db_values, vehicle={}) %}
  <a href="{{ db_values.url }}"></a>
{% endmacro %}

这是我调用它的地方:

# Assume vehicle = { 'id': '1' }
{{ vehicle.id }}
{{ db_values }}
<div class="banner-link">
  {{ banner(db_values, vehicle) }}
</div>

而这就是输出到页面上的内容:

1
{u'url': u'/test/'}
<div class="banner-link">
  <a href="/test/"></a>
</div>

直接在终端上查询mongodb的结果是:

{ 'url': 'test/{{ vehicle.id }}' }

有没有人遇到过类似的情况?我基本上想做的是让管理员界面中的某个人可以在网址中使用 令牌,这些令牌会根据页面的上下文在运行时被替换。看起来应该很简单,但jinja却一直在去掉它。

1 个回答

0

好的,我自己解决了这个问题。我的数据库里有 {{ vehicle.id }} 这样的写法,是因为我想让 jinja 解析它。但是当 jinja 没有解析它的时候(可能是因为上下文的问题),我就用了一个自定义的过滤器,现在一切都顺利了。

大概就是这个意思:

Jinja2 过滤器

from jinja2 import Environment

def replace_tokens(url, vehicle):
  if url is not None:
    url = Environment().from_string(url).render({ 'vehicle': vehicle })
  return url

# Assume db_values.url is set to '/test/{{ vehicle.id }}'
{% macro banner(db_values, vehicle={}) %}
  <a href="{{ db_values.url | replace_tokens(vehicle) }}"></a>
{% endmacro %}

撰写回答