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

如何修改Flask SQLAlchemy指定行数据,解决AttributeError属性不存在报错

错误原因

    1. 新用户首次提交姓名时的逻辑顺序错误:你先查询found_user = Users.query.filter_by(name=nm).first(),如果是首次注册的新用户,found_user会返回None,你直接把None存入了session["user"],后续取用时自然触发NoneType报错。
    1. 键名不匹配:你在session中存储用户的键是"user",但num≥2的所有逻辑中你都调用session.get("users"),多了一个字母s,永远取到None。
    1. Flask session默认不支持直接序列化SQLAlchemy模型对象,即使你存进去了后续也可能出现序列化异常、对象状态脱离数据库会话的问题,修改后无法正常提交到数据库。
    1. 路由重复:你定义了两个路径为/home的路由,会触发路由冲突。

修复方案

步骤1:调整num=0处的用户创建逻辑,改为存用户ID而非整个对象

@app.route("/test/<num>", methods=["GET", "POST"])
@app.route("/test", defaults={'num': '0'}, methods=["GET", "POST"])
def test(num):
    # 统一先获取当前用户,避免重复代码
    act_usr = None
    if "user_id" in session:
        act_usr = Users.query.get(session["user_id"])

    if num == "0":
        if request.method == "POST":
            nm = request.form["name"]
            session["name"] = nm
            found_user = Users.query.filter_by(name=nm).first()
            if not found_user:
                # 用户不存在则创建
                found_user = Users(nm, False, 0, 0, 0, 0, 0)
                db.session.add(found_user)
                db.session.commit()
            # 存用户ID而非整个对象
            session["user_id"] = found_user._id
        else:
            return render_template("test.html")

    elif num == "1":
        if request.method == "POST":
            # 先判断用户是否存在,避免报错
            if not act_usr:
                # 未登录跳转回测试起始页
                return redirect("/test")
            result = request.form.get("result", False)
            # planche n 1
            if result != "12":
                act_usr.fake = True
                db.session.commit()
        else:
            return render_template("planches/test1.html")
    # 后面所有num≥2的逻辑全部修改:
    # 1. 去掉所有session.get("users")的代码,直接用前面已经查询好的act_usr
    # 2. 先判断act_usr是否存在再做操作
    elif num == "2":
        if request.method == "POST":
            if not act_usr:
                return redirect("/test")
            result = request.form["result"]
            # planche n 2
            if result == "3":
                act_usr.d_rouge_vert += 1
                db.session.commit()
            elif result == "8":
                pass
            else:
                act_usr.biz += 1
                db.session.commit()
        else:
            return render_template("planches/test2.html")
    # 其余num=3到num=9的逻辑和num=2完全一致,替换掉原有session.get("users")的部分即可
    # ... 剩余代码保持逻辑不变,仅移除session.get("users")相关代码,改用act_usr

步骤2:删除重复的路由

删除下面这段重复定义的/home路由:

@app.route("/home")
def contact():
    return render_template("index.html")

其他优化建议

  • 可以在所有需要用户登录的答题页面前置校验act_usr是否存在,不存在直接跳转到测试起始页,避免非法访问。
  • 答题提交后可以自动跳转到下一题,不需要用户手动修改地址。

内容的提问来源于stack exchange,提问作者Maël Schmitt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:06:10