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

Flask页面跳转异常、BuildError报错及导航全局可用问题排查

Flask页面跳转问题及导航菜单修复方案

问题概述

完成登录/注册与数据库对接后,出现以下问题:

  1. 跳转报错:werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'gyrnal'. Did you mean 'login' instead?
  2. 登录成功跳转到glavnai页面后,地址栏显示login
  3. 导航菜单无法在所有页面正常使用

解决方案

一、修复gyrnal等页面跳转报错

首先排查基础匹配问题:

  • 确认templates目录下gyrnal.html文件名拼写完全一致(Linux系统区分大小写)
  • 检查模板中{{ url_for('gyrnal') }}的端点名称,必须与路由函数名def gyrnal():完全匹配

二、解决glavnai页面地址显示异常

核心原因是重复定义了相同URL的路由,Flask会自动覆盖先定义的路由规则,引发异常跳转:

  1. 合并login与login_post函数(同一个URL的GET/POST请求统一处理):
@app.route('/login', methods=['GET', 'POST'])
def login():
    msg = ''
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
        username = request.form['username']
        password = request.form['password']
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM polzovatel WHERE username = %s AND password = %s', (username, password,))
        account = cursor.fetchone()
        if account:
            session['loggedin'] = True
            session['id'] = account['id']
            session['username'] = account['username']
            return redirect(url_for('glavnai'))
        else:
            msg = 'Неверный логин или пароль'
    # GET请求或验证失败时返回登录页面
    return render_template('avtoriz.html', msg=msg)
  1. 同样合并register与register_post函数:
@app.route('/register', methods=['GET', 'POST'])
def register():
    msg = ''
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form and 'number' in request.form:
        username = request.form['username']
        password = request.form['password']
        email = request.form['email']
        number = request.form['number']
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM polzovatel WHERE username = %s', (username,))
        account = cursor.fetchone()
        if account:
            msg = 'Аккаунт уже существует'
        elif not re.match(r'[^@]+@[^@]+\.[^@]+', email):
            msg = 'Неверный формат почты'
        elif not re.match(r'[A-Za-z0-9]+', username):
            msg = 'Логин может иметь только буквы и цифры'
        elif not username or not password or not email:
            msg = 'Пожалуйста, заполните все формы'
        else:
            cursor.execute('INSERT INTO polzovatel VALUES (NULL, %s, %s, %s, %s)', (username, password, email, number,))
            mysql.connection.commit()
            msg = 'Вы успешно зарегистрировались!'
    elif request.method == 'POST':
        msg = 'Пожалуйста, заполните форму полностью'
    return render_template('registr.html', msg=msg)

合并后,登录成功跳转至glavnai时,地址栏会正确显示/glavnai。

三、实现导航菜单全局可用

  1. 替换冗余的表单跳转方式,直接使用<a>标签:
<a href="{{ url_for('glavnai') }}" class="text_menu">Главная</a>
<a href="{{ url_for('gyrnal') }}" class="text_menu">Журнал</a>
  1. 使用Flask模板继承实现菜单复用:
  • 创建基础模板templates/base.html:
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <!-- 全局导航菜单 -->
    <div class="nav-bar">
        <a href="{{ url_for('glavnai') }}" class="text_menu">Главная</a>
        <a href="{{ url_for('gyrnal') }}" class="text_menu">Журнал</a>
        <a href="{{ url_for('magazin') }}" class="text_menu">Магазин</a>
        <a href="{{ url_for('korzina') }}" class="text_menu">Корзина</a>
        {% if session.get('loggedin') %}
            <span>Привет, {{ session['username'] }}</span>
        {% else %}
            <a href="{{ url_for('login') }}">Войти</a>
            <a href="{{ url_for('register') }}">Регистрация</a>
        {% endif %}
    </div>

    <!-- 页面内容区域 -->
    {% block content %}{% endblock %}
</body>
</html>
  • 其他模板继承基础模板(以glavnai.html为例):
{% extends "base.html" %}

{% block title %}Главная{% endblock %}

{% block content %}
    <!-- 页面具体内容 -->
{% endblock %}

所有页面会自动继承导航菜单,且url_for能正确解析路由端点。

额外优化:添加登录验证保护

若需限制未登录用户访问glavnai等页面,可添加装饰器:

from functools import wraps

def login_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not session.get('loggedin'):
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated

# 给需要保护的路由添加装饰器
@app.route('/glavnai')
@login_required
def glavnai():
    return render_template('glavnai.html')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:27:57