Flask中request.form获取URL查询参数为空触发Bad Request报错
问题根因
出现该错误是因为Flask请求参数读取方式与请求类型不匹配,附带一个SQL传参格式错误:
- 模板中
<a>标签触发的是普通GET请求,参数nome携带在URL查询字符串(即?nome=Sopa部分)中,但后端使用request.form["nome"]读取参数——request.form仅能读取POST请求的表单格式请求体参数,GET请求的查询参数不会存入该对象,直接按键读取不存在的键就会返回400 Bad Request错误。 - psycopg2的
cursor.execute()方法要求参数传入序列类型(元组/列表),如果直接传入单个字符串,会将字符串按单个字符拆分迭代,导致SQL执行逻辑错误。
修复代码
将路由中取参、传参部分修改为如下内容即可:
# Show all the sub-categories of a catgory. @app.route("/categorias/sub_categorias") def show_sub_categories(): dbConn = None cursor = None try: dbConn = psycopg2.connect(DB_CONNECTION_STRING) cursor = dbConn.cursor(cursor_factory = psycopg2.extras.DictCursor) query = "SELECT categoria FROM tem_outra WHERE super_categoria=%s;" # 从GET请求查询字符串读取参数,包装为单元素元组符合execute传参要求 data = (request.args.get("nome"),) cursor.execute(query, data) return render_template("sub_categorias.html", cursor = cursor, params = request.args) except Exception as e: return str(e) finally: cursor.close() dbConn.close()
改动说明
- 将
request.form["nome"]替换为request.args.get("nome"):这是Flask读取GET请求URL查询参数的标准方式,使用.get()方法读取的好处是参数缺失时不会直接抛出400错误,会返回None,方便后续添加参数校验逻辑。 - 在参数值后添加逗号,将
data定义为单元素元组,符合psycopg2的参数传递规则,避免SQL参数解析异常。
可选优化建议
- 增加参数合法性校验:如果读取到的
nome为空,可以返回提示信息或重定向回分类列表页,避免无意义的数据库查询。 - 数据库连接与游标推荐使用
with上下文管理器编写,无需手动调用close()方法,即使代码抛出异常也能自动释放数据库资源。 - 模板中的链接不建议硬编码相对路径,可使用Flask内置的
url_for函数生成路由地址,避免后续路由修改后链接失效,示例写法:<a href="{{ url_for('show_sub_categories', nome=record[0]) }}"> Sub categorias </a>
内容的提问来源于stack exchange,提问作者Valentim Santos
相关产品推荐
相关产品推荐

