You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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即可)

关键修改点说明

  1. 提前初始化变量:在函数开头就初始化msg和各个表单变量,避免异常情况下变量未定义。
  2. 安全获取表单数据:使用request.form.get(field, default_value)替代直接索引,防止字段缺失触发KeyError。
  3. 正确处理Checkbox数据:通过getlist('ch')获取选中的Checkbox值,再用join拼接成字符串存入数据库。
  4. 修复Cursor创建:移除cursor()方法的多余参数,改为正确的con.cursor()。
  5. 调整commit位置:将con.commit()放入with语句块内,确保数据库连接处于有效状态时执行提交。
  6. 异常处理优化:判断con是否存在再执行rollback,避免因con未定义导致二次异常。

内容的提问来源于stack exchange,提问作者Kamus Suwanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:09:33