Flask跨两个不同模板的表单操作如何实现数据库统一提交
Flask分步注册表单事务统一提交实现方案
核心实现逻辑
核心思路是第一步表单提交后暂存数据不入库,第二步全部操作完成后通过数据库事务统一写入两张表,具体实现步骤如下:
1. 第一步表单数据暂存到Session,不直接写入数据库
第一个模板的基础信息表单校验通过后,不要直接执行数据库写入操作,把所有字段处理后暂存在Flask Session中,敏感信息(如密码)需提前做哈希处理不要存明文:
@app.route('/register/step1', methods=['GET', 'POST']) def register_step1(): form = UserBaseInfoForm() if form.validate_on_submit(): # 组装第一步数据存入Session step1_data = { "username": form.username.data, "email": form.email.data, "password_hash": generate_password_hash(form.password.data) # 补充user表其余所需字段 } session["step1_data"] = step1_data # 可额外增加有效期字段,避免数据长期有效:step1_data["expire_at"] = time.time() + 86400 return redirect(url_for("register_step2")) return render_template("step1.html", form=form)
如果担心Flask默认Cookie Session的安全性,可以替换为服务端Session(比如用Flask-Session扩展对接Redis)存储暂存数据。
2. 第二步操作完成后开启事务统一提交
第二步证件上传表单校验通过后,先校验第一步暂存数据是否存在,确认数据完整后开启数据库事务,同时写入两张表,任意一步报错就全部回滚,保证数据一致性:
@app.route('/register/step2', methods=['GET', 'POST']) def register_step2(): # 无第一步数据直接跳转回第一步 if "step1_data" not in session: return redirect(url_for("register_step1")) # 可选:校验第一步数据是否过期 # if session["step1_data"]["expire_at"] < time.time(): # session.pop("step1_data") # return redirect(url_for("register_step1")) form = UserDocUploadForm() if form.validate_on_submit(): try: # 写入user表数据,flush仅生成自增ID不提交事务 new_user = User(**session["step1_data"]) db.session.add(new_user) db.session.flush() # 写入关联的userdoc表数据 new_doc = UserDoc( user_id = new_user.id, id_card_url = form.id_card.data.save(save_path), # 补充userdoc表其余所需字段 ) db.session.add(new_doc) # 两张表写入都无异常再统一提交事务 db.session.commit() # 提交完成后清空Session暂存数据,避免重复提交 session.pop("step1_data") return redirect(url_for("register_success")) except Exception as e: # 任意环节报错全部回滚,不会残留脏数据 db.session.rollback() return render_template("step2.html", form=form, error="提交失败,请重试") return render_template("step2.html", form=form)
内容的提问来源于stack exchange,提问作者Abhishek Bagde
相关产品推荐
相关产品推荐

