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

