Flask如何加载下拉选框并实现前后端参数传递
错误原因
- 核心原因是混用了Jinja2模板语法和Python原生字符串格式化:你写的
{% for colour in colours[1:] %}、{{colours[0]}}都是Jinja2模板的专属语法,只能在render_template()渲染的模板文件里生效,你直接把带这些语法的字符串用.format()方法处理,Python会把所有大括号包裹的内容都识别为字符串格式化占位符,找不到对应的传参就会抛出KeyError。 - 第二是HTML语法错误:
method和action是表单<form>标签的属性,你错误写在了<select>标签上,就算渲染成功也没法正常提交参数。 - 第三是缺失POST请求处理逻辑:你之前写的
/dropdown路由只处理了GET请求返回下拉框,没有写接收POST提交参数的逻辑,自然拿不到用户选中的值。
推荐实现方案
推荐完全使用Flask原生的模板渲染机制实现,逻辑清晰易维护,实现步骤如下:
- 首先在你的项目根目录下创建
templates文件夹,在里面新建select.html,内容如下:
<!DOCTYPE html> <html> <body> <!-- 错误提示位 --> {{ errors if errors }} <form method="post" action="/dropdown"> <select name="colour"> <option value="{{colours[0]}}" selected>{{colours[0]}}</option> {% for colour in colours[1:] %} <option value="{{colour}}">{{colour}}</option> {% endfor %} </select> <p><input type="submit" value="Do calculation" /></p> </form> </body> </html>
- 修改
/dropdown路由的逻辑,同时处理GET和POST请求,拿到用户选中的参数:
@app.route("/dropdown", methods=["GET", "POST"]) def select(): errors = "" colours = ['Red', 'Blue', 'Black', 'Orange'] # 处理POST提交 if request.method == "POST": selected_colour = request.form.get("colour") # 拿到选中值后就可以调用你自己的业务逻辑处理 if selected_colour: # 这里替换成你自己的计算逻辑即可 return f''' <html> <body> <p>你选中的颜色是 {selected_colour}</p> <p><a href="/dropdown">点击此处重新选择</a></p> </body> </html> ''' else: errors += "<p>请先选择选项后提交</p>" # GET请求或者提交有误时返回下拉框页面 return render_template('select.html', colours=colours, errors=errors)
如果你不想单独维护模板文件,硬写HTML字符串的话可以直接用Python逻辑拼接选项,不要带Jinja语法:
# 先生成option的HTML字符串 option_html = f'<option value="{colours[0]}" selected>{colours[0]}</option>' for colour in colours[1:]: option_html += f'<option value="{colour}">{colour}</option>' # 拼入整体HTML返回 return f''' <html> <body> {errors} <form method="post" action="."> <select name="colour"> {option_html} </select> <p><input type="submit" value="Do calculation" /></p> </form> </body> </html> ''' 内容的提问来源于stack exchange,提问作者RichardWiggles
相关产品推荐
相关产品推荐

