首页 > 解决方案 > 如何在 Flask 中将字典传递给 url_for

问题描述

我想将端点传递到url_for端点包含名称为变量name=value的参数的位置。

基本上,如果我可以传递参数变量名称,我有多个模板可以折叠成一个模板。一种解决方案可能是传递字典,但可能还有其他方法。我绝对可以通过在渲染之前对 html jinja 生成的进行后处理来做到这一点。

我已经尝试了所有我能想到的明显技巧,包括嵌套{{ }}

所以在我的路线代码的末尾我有

# routes.py
...
@bp.route('/customer/add/prompt/<customer_id>',methods = ['POST', 'GET'])
@login_required
def customer_add_prompt(customer_id):
    #code code code
    return render_template('customer_add.html',
        customer_id = customer_id)

事实上,我有很多针对不同主题(客户、产品、发票)的路线,它们以这种方式结束。因此,对于每个主题,我都需要一个看起来像这样的 jinja 模板。

# customer_add.html
...   
<form action = "{{ url_for(customer_add, customer_id = customer_id) }}" method = "POST">       
    <-- html htlm htlm -->
</form>

当用户提交表单时,端点将customer_add被遵循并customer_add期望并被传递customer_id = 1234(或任何值)。

这就是问题所在。我应该能够像这样组合所有模板。

# subject_add.html
...   
<form action = "{{ url_for(subject_target, subject = subject_id) }}" method = "POST">       
    <-- html htlm htlm -->
</form>

然后像这样渲染它。

# routes.py
...
@bp.route('/customer/add/<customer_id>',methods = ['POST', 'GET'])
@login_required
def customer_add_prompt(customer_id):
    #code code code
    subject_target = 'customer_add.html'
    subject = 'customer_id'
    subject_id = customer_id
    return render_template(subject_target,
        subject = subject_id)

当我这样做时,我收到一条错误消息Could not build url for endpoint 'customer_add' with values ['subject']. Did you forget to specify values ['entity_id']?

测试表明,subject_targetsubject_id得到替代罚款。Butsubject没有被替换,因为在url_for语法中它是一个参数名称,并且端点期望一个名为customer_idnot的变量的值subject

我希望有一种方法可以说明 jinja 中的参数名称。概括我可能想传递一个参数字典。

理想情况下,我可以这样通过d = {'subject': x, ...}url_for(subject_action, d)Jinja 会认为这等同于url_for(subject_action, subject=1234, ...x=1234 时。

标签: pythonflask

解决方案


您可以将参数添加到url_for(). 根据文档

目标端点未知的变量参数作为查询参数附加到生成的 URL

所以你可以做

<form action = "{{ url_for(action_target, 
                           subject_type=subject_id, 
                           2nd_variable=2nd_variable, 
                           etc...) }}" method = "POST">

但正如 wonka 所说,您最好将数据作为POST参数发送。

如果我误解了并且您试图在您的视图中传递来自您的render_template呼叫的数据,那么您也可以这样做。

return render_template('template_name.html', 
                        data={
                            "action_type": "action",
                            "subject_type": subject_value
                        })  

然后您可以在您的模板中使用{{data["subject_type"]}}


推荐阅读