Flask+SQLite3中Checkbox数据插入遇UnboundLocalError求助
Flask表单提交Checkbox后出现UnboundLocalError的解决方法
问题重现
在Flask项目中实现含文本框和Checkbox的表单提交功能,移除Checkbox时代码正常运行,加入Checkbox后点击提交出现错误:
UnboundLocalError: local variable 'msg' referenced before assignment
错误原因分析
查看你的视图函数代码,存在以下几个关键问题:
- 不存在的表单字段引用:代码中
skills = request.form['skills'],但HTML模板里并没有name为skills的输入框,只有name为ch的Checkbox,这行代码会直接触发KeyError,进入异常处理块。 - Cursor创建错误:
cur = con.cursor(v)是错误用法,cursor()方法不需要传入参数,传入参数会导致报错。 - 连接管理错误:
con.commit()写在with语句块外部,而with sql.connect(...) as con会在块结束后自动管理连接状态,外部执行commit可能失效;同时如果在with块之前就触发异常(比如上面的KeyError),con变量还未定义,异常处理里的con.rollback()会再次报错,导致msg无法被赋值,最终在finally块中引用msg时触发UnboundLocalError。 - 代码执行顺序问题:
finally块中return语句在con.close()之前,导致con.close()永远不会执行,不过with语句已经自动管理连接,这行代码本身多余。
修正后的代码
视图函数修正版
def addrec(): msg = "" name = city = email = language = addr = pin = skills = "" if request.method == 'POST': try: # 用get方法取值,避免字段缺失触发KeyError name = request.form.get('name', '') city = request.form.get('city', '') email = request.form.get('email', '') language = request.form.get('language', '') addr = request.form.get('addr', '') pin = request.form.get('pin', '') # 获取Checkbox的值并处理 skill_list = request.form.getlist('ch') skills = ','.join(skill_list) with sql.connect("database.db") as con: cur = con.cursor() # 正确创建cursor,无需传参 cur.execute( 'INSERT INTO students (name,city,email,language,addr,pin,skills) VALUES (?,?,?,?,?,?,?)', (name,city,email,language,addr,pin,skills) ) con.commit() # 将commit放入with块内,确保连接有效 msg = "success! insert operation" except Exception as e: # 先判断con是否存在再执行rollback if 'con' in locals(): con.rollback() msg = f"error in insert operation: {str(e)}" finally: return render_template("result.html", msg=msg, name=name, city=city, email=email, language=language, addr=addr, pin=pin, skills=skills)
HTML模板无需修改(确保Checkbox的name为ch即可)
关键修改点说明
- 提前初始化变量:在函数开头就初始化
msg和各个表单变量,避免异常情况下变量未定义。 - 安全获取表单数据:使用
request.form.get(field, default_value)替代直接索引,防止字段缺失触发KeyError。 - 正确处理Checkbox数据:通过
getlist('ch')获取选中的Checkbox值,再用join拼接成字符串存入数据库。 - 修复Cursor创建:移除
cursor()方法的多余参数,改为正确的con.cursor()。 - 调整commit位置:将
con.commit()放入with语句块内,确保数据库连接处于有效状态时执行提交。 - 异常处理优化:判断
con是否存在再执行rollback,避免因con未定义导致二次异常。
内容的提问来源于stack exchange,提问作者Kamus Suwanto
相关产品推荐
相关产品推荐

