从 jinja2 调用 Python 函数

2025-03-18 08:54:00
admin
原创
44
摘要:问题描述:我正在使用 jinja2,我想调用一个 python 函数作为辅助程序,使用类似于调用宏的语法。jinja2 似乎有意阻止我进行函数调用,并坚持让我通过将函数作为宏复制到模板中来重复自己。 有没有直接的方法可以做到这一点? 并且,有没有办法导入一整套 python 函数并让它们从 jinja2 访问...

问题描述:

我正在使用 jinja2,我想调用一个 python 函数作为辅助程序,使用类似于调用宏的语法。jinja2 似乎有意阻止我进行函数调用,并坚持让我通过将函数作为宏复制到模板中来重复自己。

有没有直接的方法可以做到这一点? 并且,有没有办法导入一整套 python 函数并让它们从 jinja2 访问,而无需经过大量的繁琐步骤(例如编写扩展)?


解决方案 1:

对于使用 Flask 的用户,请将其放入__init__.py

def clever_function():
    return u'HELLO'

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

并在您的模板中调用它{{ clever_function() }}

解决方案 2:

注意:这是 Flask 特有的!

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

可以轻松创建变量:

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

以上内容可以在 Flask 的 Jinja2 模板中使用,如下所示:

{{ myexample }}

(输出This is an example

以及成熟的功能:

@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) }}

(输出输入价格和货币符号)

或者,你可以使用嵌入到 Flask 中的jinja 过滤器。例如使用装饰器:

@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 %}

解决方案 3:

我认为 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

解决方案 4:

from jinja2 import Template

def custom_function(a):
    return a.replace('o', 'ay')

template = Template('Hey, my name is {{ custom_function(first_name) }} {{ func2(last_name) }}')
template.globals['custom_function'] = custom_function

您还可以按照Matroskin 的答案在字段中给出该函数

fields = {'first_name': 'Jo', 'last_name': 'Ko', 'func2': custom_function}
print template.render(**fields)

将会输出:

Hey, my name is Jay Kay

与 Jinja2 版本 2.7.3 兼容

如果你想要一个装饰器来简化函数的定义,template.globals请查看Bruno Bronosky 的答案

解决方案 5:

我喜欢@AJP的回答。我逐字逐句地使用它,直到我得到了很多函数。然后我切换到Python函数装饰器。

from jinja2 import Template

template = '''
Hi, my name is {{ custom_function1(first_name) }}
My name is {{ custom_function2(first_name) }}
My name is {{ custom_function3(first_name) }}
'''
jinga_html_template = Template(template)

def template_function(func):
    jinga_html_template.globals[func.__name__] = func
    return func

@template_function
def custom_function1(a):
    return a.replace('o', 'ay')

@template_function
def custom_function2(a):
    return a.replace('o', 'ill')

@template_function
def custom_function3(a):
    return 'Slim Shady'

fields = {'first_name': 'Jo'}
print(jinga_html_template.render(**fields))

好东西函数有一个__name__

解决方案 6:

从未在官方文档或 Stack Overflow 上看到过如此简单的方法,但是当我发现这个时我感到很惊讶:

# jinja2.__version__ == 2.8
from jinja2 import Template

def calcName(n, i):
    return ' '.join([n] * i)

template = Template("Hello {{ calcName('Gandalf', 2) }}")

template.render(calcName=calcName)
# or
template.render({'calcName': calcName})

解决方案 7:

有一个更简单的决定。

@app.route('/x')
def x():
    return render_template('test.html', foo=y)

def y(text):
    return text

然后,在test.html中:

{{ foo('hi') }}

解决方案 8:

要从 Jinja2 调用 Python 函数,您可以使用与 类似的自定义过滤器globals

它非常简单实用。在文件 myTemplate.txt 中,我写道:

{{ data | pythonFct }}

在 Python 脚本中:

import jinja2

def pythonFct(data):
    return "This is my data: {0}".format(data)
    
input="my custom filter works!"
  
loader = jinja2.FileSystemLoader(path or './')
env = jinja2.Environment(loader=loader)
env.filters['pythonFct'] = pythonFct
result = env.get_template("myTemplate.txt").render(data=input)
print(result)

解决方案 9:

使用 lambda 将模板连接到主代码

return render_template("clever_template", clever_function=lambda x: clever_function x)

然后就可以无缝调用模板中的函数了

{{clever_function(value)}}

解决方案 10:

有什么方法可以导入一整套 python 函数并让 jinja2 访问它们?

是的,除了上面的其他答案之外,这对我有用。

创建一个类并用相关方法填充它,例如

class Test_jinja_object:

    def __init__(self):
        self.myvar = 'sample_var'

    def clever_function (self):
        return 'hello' 

然后在视图函数中创建类的一个实例,并将结果对象作为 render_template 函数的参数传递给模板

my_obj = Test_jinja_object()

现在,在你的模板中,你可以像这样调用 Jinja 中的类方法

{{ my_obj.clever_function () }}

解决方案 11:

要导入所有内置函数,您可以使用:

app.jinja_env.globals.update(__builtins__)

如果这不起作用,.__dict__请添加。__builtins__

根据John32323 的回答。

解决方案 12:

@John32323 的答案是一个非常干净的解决方案。

这是相同的,但保存到单独的文件中,可能更干净。

创建帮助文件

应用程序\helper.py

from app import app

def clever_function_1():
    return u'HELLO'

def clever_function_2(a, b):
    return a + b



app.jinja_env.globals.update(
    clever_function_1=clever_function_1,
    clever_function_2=clever_function_2,
)

从应用程序导入

应用程序

from app import routes
from app import helper   # add this one

像这样使用

应用程序\模板\some.html


{{ clever_function_1() }}
{{ clever_function_2(a, b) }}

解决方案 13:

对于使用 FastApi 的用户,请将其放入__init__.py

from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates")

def clever_function():
    return u'HELLO'

templates.env.globals.update(clever_function=clever_function)

并在您的模板中调用它{{ clever_function() }}

解决方案 14:

如果你使用 Django 来执行此操作,则只需传递带有上下文的函数即可:

context = {
    'title':'My title',
    'str': str,
}
...
return render(request, 'index.html', context)

现在你将能够使用strjinja2 模板中的函数

解决方案 15:

Creating a global function without passing to the template

@app.template_global('double')
def double(n):
    return 2 * n

Jinja Usage`enter code here`

{{double(77)}}

Or
Creating a filter in jinja.


@app.template_filter('geo_stuff')
def hellome(a,b='dadadd'):
    d=a+'it is jerry'
    return d
jinja use
{{'foo'|geo_stuff}}
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用