Flask请求URL未找到及密码更新保存失败问题求助
问题分析与修复方案
问题描述
收到错误提示:“请求的URL在服务器上未找到。如果您手动输入了URL,请检查拼写并重试”。
确认问题出在表单action属性:若改为指向login路由,所有路由可正常运行,用户能输入新密码并跳转到登录页,但无法保存新密码并实现用新密码登录的功能。
代码问题排查
前端问题
- 表单action中的
{id}是硬编码字符串,jinja2模板不会解析,导致实际请求URL为/update/{id},与后端/update/<int:id>路由不匹配,触发404错误。 - 提交按钮渲染错误:
{{ form.submit}}缺少括号,无法正确生成提交按钮的HTML代码。
后端问题
- 密码未加密存储:直接将明文密码赋值给
userPass.password,后续登录验证时无法匹配哈希密码。 - 逻辑顺序错误:
return render_template()之后的redirect()永远不会执行,因为return会终止函数运行。 - 无效的异常处理:提交失败后没有回滚数据库会话,可能导致数据不一致;且
except:捕获所有异常,不利于定位具体问题。 - 用户查询容错性差:
User.query.get(id)在用户不存在时返回None,后续操作会引发错误。
修复步骤
1. 前端表单修复
- 使用jinja2的
url_for生成正确的路由地址,确保action指向实际的用户修改接口。 - 修正提交按钮的渲染语法,添加括号生成完整的按钮HTML。
2. 后端逻辑修复
- 密码哈希处理:使用
werkzeug.security.generate_password_hash对密码加密后存储,或调用用户模型的set_password方法(如果已定义)。 - 调整跳转逻辑:提交成功后直接重定向到登录页,异常时回滚数据库会话并跳转回修改页面。
- 优化用户查询:用
get_or_404替代get,用户不存在时直接返回404错误。 - 移除无效代码:删除所有
return之后的redirect语句。
修复后代码示例
后端代码
from flask import render_template, request, redirect, url_for, flash from flask_login import login_required from werkzeug.security import generate_password_hash from your_app import db, User, UpdatePasswordForm # 替换为实际的导入路径 @app.route('/update/<int:id>', methods=['GET', 'POST']) @login_required def update(id): form = UpdatePasswordForm() userPass = User.query.get_or_404(id) if request.method == "POST": # 加密密码后存储 userPass.password = generate_password_hash(request.form['password']) # 如果User模型有set_password方法,可改用:userPass.set_password(request.form['password']) try: db.session.commit() flash("密码修改成功!") return redirect(url_for('login')) except Exception as e: db.session.rollback() flash(f"修改失败:{str(e)}") return redirect(url_for('update', id=id)) else: return render_template("update.html", form=form, userPass=userPass, id=id)
前端HTML代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>修改密码</title> </head> <body> <h1>修改密码</h1> <form action="{{ url_for('update', id=id) }}" method="POST"> {{ form.password(class="form-control", value=userPass.password) }} {{ form.submit() }} </form> <!-- 显示提示消息 --> {% with messages = get_flashed_messages() %} {% if messages %} {% for msg in messages %} <div style="color: red;">{{ msg }}</div> {% endfor %} {% endif %} {% endwith %} </body> </html>
内容的提问来源于stack exchange,提问作者fasterjake
相关产品推荐
相关产品推荐

