如何在Jinja模板中导入Python模块?

73 投票
6 回答
62351 浏览
提问于 2025-04-16 10:47

我可以把一个Python模块导入到Jinja模板中,这样就能使用它的功能吗?

举个例子,我有一个叫format.py的文件,里面有一些格式化日期和时间的方法。在一个Jinja宏里,我能这样做吗?

{% from 'dates/format.py' import timesince %}

{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}

因为format.py不是一个模板,所以上面的代码给我报了这个错:

UndefinedError: the template 'dates/format.py' (imported on line 2 in 'dates/macros.html') does not export the requested name 'timesince'

...但我在想有没有其他方法可以做到这一点。

6 个回答

21

模板本身并不知道import这个指令,但你可以通过importlib来教它:

import importlib
my_template.render( imp0rt = importlib.import_module )  # can't use 'import', because it's reserved

(你也可以通过传递一个带有dict的参数,把它命名为"import"

kwargs = { 'import' : importlib.import_module }
my_template.render( **kwargs )

然后在jinja模板中,你就可以导入任何模块了:

{% set time = imp0rt( 'time' ) %}
{{ time.time() }}
44

只需将函数传递到模板中,像这样

from dates.format import timesince
your_template.render(timesince)

然后在模板中,就像调用其他函数一样调用它,

{% macro time(mytime) %}
    <a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}

在Python中,函数是非常重要的东西,所以你可以像对待其他任何东西一样传递它们。你甚至可以传递整个模块,如果你想的话。

70

在模板里面,不可以直接导入Python代码。

要做到这一点,你需要把这个函数注册为一个jinja2的自定义过滤器,方法如下:

在你的Python文件中:

from dates.format import timesince

environment = jinja2.Environment(whatever)
environment.filters['timesince'] = timesince
# render template here

在你的模板中:

{% macro time(mytime) %}
<a title="{{ mytime }}">{{ mytime|timesince }}</a>
{% endmacro %}

撰写回答