使用 Python3 Flask Jinja2 模板中用户输入的参数调用函数

Call function with arguments from user input in Python3 Flask Jinja2 template

我正在编写一个 Web 应用程序,它以 HTML 形式接受用 Jinja2 编写的用户输入。 根据输入,我设置了在 Jinja2 中定义的变量,然后我想将其作为位置参数传递给在我的 __init__.py 文件或 main.py 文件中定义的另一个函数。

Python version==3.6.8  
Flask==2.0.1  
Jinja2==3.0.1  

我尝试了很多方法来实现这一点,但没有成功(尝试调用该函数时出现未定义的错误),包括遵循此线程中的建议:Call a python function from jinja2

我的网络应用程序的文件结构如下所示:
https://prntscr.com/1rlt3cl(我不能post图片,因为我没有足够的信誉点,所以我上传了它)。

我在我的 form.html 文件中接收用户输入,我将其传递给 data.html 文件。

<form action="/data" method = "POST">
    <p>Various inputs<input type = "number" name = "random" /></p>
    <p><input type = "submit" value = "Submit" /></p>
</form>

data.html 文件中,我想接受用户输入的值,并调用一个位于我所有 __init__.py 文件中的函数(不确定实际上是哪个 Flask看着):

{% set ns1 = namespace(random=None) %}   
{% for key,value in form_data.items() %}
    {% if key ==  "iterations" %}
        {%- set ns1.iterations = value -%}
    {% endif %}
{% endfor %}

{{ clever_function(random) }}

clever_function 在 __init__.py 文件中定义如下:

from jinja2 import Template 
def clever_function(): 
    return "Hello"
    
template = Template("{{ clever_function() }}")
template.globals['clever_function'] = clever_function  

当 运行 我的 webapp/main.py 应用程序呈现表单/数据模板时,如下所示:

@app.route('/form')
def form():
    return render_template('form.html')
 
@app.route('/data', methods = ['POST', 'GET'])
def data():
    if request.method == 'GET':
        return f"The URL /data is accessed directly. Try going to '/form' to submit form"
    if request.method == 'POST':
        form_data = request.form
        return render_template('data.html',form_data = form_data)  

我收到以下异常:

jinja2.exceptions.UndefinedError: 'clever_function' is undefined

您使用的代码是对直接定义模板内独占使用的简要说明。
要在 render_template 使用的模板中使用自定义函数,您必须将其添加到 jinja 环境的字典全局变量中。

from flask import Flask
from flask import render_template, request

def clever_function(value):
    return value**2

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

@app.route('/form')
def form():
    return render_template('form.html')

@app.route('/data', methods=['POST'])
def data():
    return render_template('data.html', form_data=request.form)

以后本环境加载调用的所有模板都可以调用该函数

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <p>Result: {{ clever_function(form_data.get('random', 0) | int) }}</p>
  </body>
</html>

请记住,如果你想用任何方式调用它,定义的函数必须接受参数。


使用命名空间对象时也出现了错误。您应该再看看 jinja2 中作业的文档。

这是一个基于您的代码的小示例。

{% set ns1 = namespace(random=0) %}
{% for k,v in form_data.items() %}
  {% if k == 'random' %}
    {% set ns1.random = v | int %}
  {% endif %}
{% endfor %}
<p>Value is {{ns1.random}}</p>