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

Flask登录验证通过后无法跳转至admin页面的问题排查

Flask登录跳转失败问题排查

问题现象

运行Flask项目时,用户输入正确的用户名和密码后无法完成页面跳转,登录接口触发路由构建错误。

相关代码

app.py

from flask import Flask, render_template, request, redirect, url_for, session
import json,admin,teacher,student,quiz_api
from models import Student, Teacher, db, app

# from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.secret_key = 'secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///quiz.db'
db = SQLAlchemy(app)

with app.app_context():
    db.create_all()
# db.create_all()



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


@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    user_type = request.form['type']
    if user_type == 'Teacher':
        user = Teacher.query.filter_by(username=username).first()
        if user is None:
            return "incorrect username"
        else:
            if user.password == password:
                session['username'] = username
                session['id'] = user.id
                return redirect(url_for('teacher_index'))
            else:
                return "incorrect password"
    if user_type == 'Admin':
        if username == 'admin' and password == 'admin':
            print("inside admin ------")
            return redirect(url_for('admin'))
    else:
        user = Student.query.filter_by(username=username).first()
        if user is None:
            return "incorrect username"
        else:
            if user.password == password:
                session['username'] = username
                session['id'] = user.id
                return redirect(url_for('student_index'))
            else:
                return "incorrect password"


@app.route("/logout", methods=['POST'])
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))


if __name__ == "__main__":
    app.secret_key = 'super secret key'
    app.config['SESSION_TYPE'] = 'filesystem'
    app.debug = True
    app.run()

admin.py

from flask import render_template, request, redirect, url_for
from models import Teacher, Student, Score, Quiz, app, db


@app.route('/admin')
def admin():
    print("hello inside admin")
    if 'username' == None:
        return redirect(url_for("index"))
    teachers = Teacher.query.all()
    students = Student.query.all()
    user_data = {'students': students, 'teachers': teachers}
    print(user_data)
    return render_template("admin.html", user_data=user_data)


@app.route('/delete_student/<student_id>')
def delete_student(student_id):
    student = Student.query.filter_by(id=student_id).first()
    student_quiz_scores = Score.query.filter_by(student_id=student.id).all()
    for student_score in student_quiz_scores:
        db.session.delete(student_score)
        db.session.commit()
    db.session.delete(student)
    db.session.commit()
    return redirect(url_for('admin'))


@app.route('/delete_teacher/<teacher_id>')
def delete_teacher(teacher_id):
    teacher = Teacher.query.filter_by(id=teacher_id).first()
    # quizes_of_teacher = Quiz.query.filter_by(teacher_id=teacher.id)
    for quiz in Quiz.query.filter_by(teacher_id=teacher.id):
        db.session.delete(quiz)
        db.session.commit()
    db.session.delete(teacher)
    db.session.commit()
    return redirect(url_for('admin'))


@app.route('/update_teacher', methods=['POST', 'GET'])
def update_teacher():
    teacher_id = request.form['t_id']
    teacher_username = request.form['t_username']
    teacher_password = request.form['t_password']

    teacher = Teacher.query.filter_by(id=teacher_id).first()
    teacher.username = teacher_username
    teacher.password = teacher_password
    db.session.commit()
    return redirect(url_for('admin'))


@app.route('/update_student', methods=['POST', 'GET'])
def update_student():
    student_id = request.form['s_id']
    student_username = request.form['s_username']
    student_password = request.form['s_password']

    student = Student.query.filter_by(id=student_id).first()
    student.username = student_username
    student.password = student_password
    db.session.commit()
    return redirect(url_for('admin'))


@app.route("/insert_teacher", methods=['POST'])
def insert_teacher():
    name = request.form["teacher_name"]
    password = request.form["teacher_password"]
    teacher = Teacher.query.filter_by(username=name).first()
    if teacher is None:
        teacher = Teacher(username=name, password=password)
        db.session.add(teacher)
        db.session.add(teacher)
        db.session.commit()
        return redirect(url_for("admin"))
    else:
        return "404 Duplicate Name Error!"


@app.route("/insert_student", methods=['POST'])
def insert_student():
    name = request.form["student_name"]
    password = request.form["student_password"]
    student = Student.query.filter_by(username=name).first()
    if student is None:
        student = Student(username=name, password=password)
        db.session.add(student)
        db.session.commit()
        return redirect(url_for("admin"))
    else:
        return "404 Duplicate Name Error!"

错误日志

inside admin ------
[2024-04-26 22:22:52,567] ERROR in app: Exception on /login [POST]
Traceback (most recent call last):
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\app.py", line 1463, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\app.py", line 855, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\temp\Quiz\quiz_management_system_final\app.py", line 43, in login
    return redirect(url_for('admin'))
                    ^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\helpers.py", line 220, in url_for
           ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\flask\app.py", line 1074, in url_for
    return self.handle_url_build_error(error, endpoint, values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    rv = url_adapter.build(  # type: ignore[union-attr]
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\vatsal\miniconda3\Lib\site-packages\werkzeug\routing\map.py", line 919, in build
    raise BuildError(endpoint, values, method, self)

问题分析与解决方案

核心问题

错误提示BuildError,说明url_for('admin')找不到对应的路由端点。根源是存在两个独立的Flask应用实例:

  1. app.py中先从models导入了app,但随后又重新创建了app = Flask(__name__),覆盖了导入的实例
  2. admin.py中使用的是models里的app实例,其注册的路由没有被当前运行的app.py中的实例识别

修复步骤

  1. 统一Flask应用实例
    修改app.py,删除重复创建的app和db实例,直接使用从models导入的对象:

    from flask import Flask, render_template, request, redirect, url_for, session
    import json,admin,teacher,student,quiz_api
    from models import Student, Teacher, db, app
    
    # 移除以下重复代码
    # app = Flask(__name__)
    # app.secret_key = 'secret_key'
    # app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///quiz.db'
    # db = SQLAlchemy(app)
    
    with app.app_context():
        db.create_all()
    
    # 后续代码保持不变...
    
  2. 修复admin.py中的登录校验逻辑
    admin视图中的if 'username' == None逻辑错误,应该检查session中是否存在username:

    @app.route('/admin')
    def admin():
        print("hello inside admin")
        if 'username' not in session:  # 修正此处
            return redirect(url_for("index"))
        # 后续代码保持不变...
    
  3. 修复admin.py中的重复添加数据问题
    insert_teacher函数中重复执行了db.session.add(teacher),删除其中一条:

    @app.route("/insert_teacher", methods=['POST'])
    def insert_teacher():
        name = request.form["teacher_name"]
        password = request.form["teacher_password"]
        teacher = Teacher.query.filter_by(username=name).first()
        if teacher is None:
            teacher = Teacher(username=name, password=password)
            db.session.add(teacher)
            # 移除重复的db.session.add(teacher)
            db.session.commit()
            return redirect(url_for("admin"))
        else:
            return "404 Duplicate Name Error!"
    
  4. 确保子模块路由被正确注册
    保证admin.py、teacher.py等模块在app.py启动前被导入,这样它们的路由才能注册到统一的app实例上。当前app.py已经导入了admin,这部分没问题。

完成以上修改后,重新启动项目,登录admin账号即可正常跳转。

内容的提问来源于stack exchange,提问作者vatsal mangukiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:54:56