在jinja2中调用python函数

211 投票
15 回答
222419 浏览
提问于 2025-04-16 17:50

我正在使用jinja2,想要像调用宏一样调用一个Python函数作为辅助工具。可是,jinja2似乎不太想让我直接调用函数,反而让我重复自己,把函数复制到模板里当作宏来用。

有没有什么简单的方法可以做到这一点?还有没有办法把一整套Python函数导入到jinja2中,让它们可以直接使用,而不需要经过很多复杂的步骤(比如写扩展)?

15 个回答

97

我觉得jinja故意让在模板中运行“任意”python代码变得困难。它想要传达一个观点,那就是模板中逻辑越少越好。

你可以在一个Environment实例中操作全局命名空间,来添加对你函数的引用。不过,这个操作必须在你加载任何模板之前完成。比如:

from jinja2 import Environment, FileSystemLoader

def clever_function(a, b):
    return u''.join([b, a])

env = Environment(loader=FileSystemLoader('/path/to/templates'))
env.globals['clever_function'] = clever_function
175

注意:这特指Flask!

我知道这篇文章有点旧了,但在Flask的新版本中,有更好的方法可以做到这一点,使用的是上下文处理器。

变量可以很容易地创建:

@app.context_processor
def example():
    return dict(myexample='This is an example')

上面的内容可以在Flask的Jinja2模板中这样使用:

{{ myexample }}

(这会输出 这是一个例子)

还可以创建完整的函数:

@app.context_processor
def utility_processor():
    def format_price(amount, currency=u'€'):
        return u'{0:.2f}{1}'.format(amount, currency)
    return dict(format_price=format_price)

上面的内容这样使用时:

{{ format_price(0.33) }}

(这会输出带有货币符号的输入价格)

另外,你可以使用 jinja过滤器,这是Flask自带的。比如,使用装饰器:

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

或者,不使用装饰器,手动注册这个函数:

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

通过以上两种方法应用的过滤器可以这样使用:

{% for x in mylist | reverse %}
{% endfor %}
269

对于使用Flask的人来说,把这个放在你的 __init__.py 文件里:

def clever_function():
    return u'HELLO'

app.jinja_env.globals.update(clever_function=clever_function)

然后在你的模板中用 {{ clever_function() }} 来调用它。

撰写回答