Flask下拉菜单提交表单报400 Bad Request KeyError 'newPOTM'求助
问题根因
- 直接触发
KeyError: 'newPOTM'的原因是POST表单参数获取方式错误:你提交表单用的是method="POST",但后端用request.args读取参数,request.args仅用来读取URL后的查询参数,POST表单的参数存放在请求体中,需要用request.form读取。 - 第二个隐藏问题是SQL查询结果未读取就直接运算:
conn.execute()执行查询后返回的是游标对象,不是查询结果值,必须调用.fetchone()拿到结果行之后才能读取字段值,不然后续做加法运算会抛出类型错误。 - 第三个可优化点是HTML用文本输入框作为下拉选项,用户可能误修改输入框内容,建议改成不可编辑的按钮类型更合理。
修复代码
1. 修正app.py代码
import sqlite3, logging from flask import Flask, render_template, request, url_for, flash, redirect, jsonify from werkzeug.exceptions import abort app = Flask(__name__, static_url_path='/static') app.config['SECRET_KEY'] = 'NotForYou' def get_db_connection(): conn = sqlite3.connect('/root/ilms/ilmh.db') conn.row_factory = sqlite3.Row return conn @app.route('/potm',methods=["POST","GET"]) def potm(): conn = get_db_connection() if request.method == 'POST': # 改用request.form取POST表单参数 Name = request.form['newPOTM'] # 读取查询结果,空表场景默认赋值1 maxID_row = conn.execute('SELECT MAX(id) FROM POTM').fetchone() newID = maxID_row[0] + 1 if maxID_row[0] is not None else 1 print(newID) maxOrder_row = conn.execute('SELECT MAX(listorder) FROM POTM').fetchone() newOrder = maxOrder_row[0] + 1 if maxOrder_row[0] is not None else 1 print(newOrder) conn.execute('INSERT INTO POTM (id, player, listorder) VALUES (?, ?, ?)', (newID, Name, newOrder)) conn.commit() conn.close() return redirect(url_for('potm')) dragdrop = conn.execute("SELECT * FROM POTM ORDER BY listorder ASC") dropdown = conn.execute('SELECT Name FROM alltime ORDER BY Name ASC').fetchall() return render_template('potm.html', dragdrop=dragdrop, dropdown=dropdown)
2. 可选优化HTML代码(避免用户误改选项内容)
把文本输入框改成submit按钮,不需要额外绑定onclick事件即可正常提交:
<div class="container"> <div class="row justify-content-md-center"> <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Add Player </button> <div class="dropdown-menu pre-scrollable" aria-labelledby="dropdownMenu2"> <form method="POST"> {% for item in dropdown %} <button type="submit" class="dropdown-item" name="newPOTM" value="{{ item['Name'] }}"> {{ item['Name'] }} </button> {% endfor %} </form> </div> </div> </div> </div>
内容的提问来源于stack exchange,提问作者fk1
相关产品推荐
相关产品推荐

