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

Flask+MySQL注册功能出现NameError/UnboundLocalError求助

Flask+MySQL注册登录系统变量未定义问题解决方案

问题概述

在Mac上基于Flask+MySQL开发用户注册登录系统时,反复遭遇NameError和UnboundLocalError,所有表单变量均提示未定义。尝试过global声明变量但不推荐使用,寻求合理解决方案。

报错示例

File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 1519, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 1517, in full_dispatch_request
rv = self.dispatch_request()
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/flask/app.py", line 1503, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/Users/neil_shrivastava/code-name-sidious/market/routes.py", line 78, in register
cursor.execute('SELECT * FROM accounts WHERE username = %s', (username,))
NameError: name 'username' is not defined

问题根源

  1. 变量作用域错误:
    • login函数中,username和password仅在POST请求的if分支内定义,分支外执行数据库查询时会找不到变量。
    • register函数中,使用global声明完全没必要,且当请求为GET或POST参数不全时,username等变量未被赋值,后续执行数据库操作时触发错误。
  2. 代码逻辑缩进错误:部分数据库操作和验证代码未放在正确的条件分支内,导致非POST请求时也会执行。

修复后的完整代码

from flask import Flask, render_template, request, redirect, url_for, session
from flask_mysqldb import MySQL
import MySQLdb.cursors
import re

app = Flask(__name__)
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''
app.config['MYSQL_DB'] = 'weather_db'
app.config['SECRET_KEY'] = ''

mysql = MySQL(app)

@app.route('/')
@app.route('/about-team')
def about_team():
    return render_template('about-team.html')

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

@app.route('/login', methods=['GET', 'POST'])
def login():
    msg = ''
    # 仅在POST请求且参数齐全时处理登录逻辑
    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 user 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 'Logged in successfully!'
        else:
            msg = 'Incorrect username/password!'
    # GET请求或参数不全时返回登录页面
    return render_template('login.html', msg=msg)

@app.route('/register', methods=['GET', 'POST'])
def register():
    msg = ''
    # 初始化变量,避免未定义错误
    username = password = email_address = ''
    
    if request.method == 'POST':
        # 检查表单参数是否齐全
        if 'username' in request.form and 'password' in request.form and 'email' in request.form:
            username = request.form['username']
            password = request.form['password']
            email_address = request.form['email']
            
            # 验证账号是否存在
            cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
            cursor.execute('SELECT * FROM accounts WHERE username = %s', (username,))
            account = cursor.fetchone()
            
            if account:
                msg = 'Account already exists!'
            elif not re.match(r'[^@]+@[^@]+\.[^@]+', email_address):
                msg = 'Invalid email address!'
            elif not re.match(r'[A-Za-z0-9]+', username):
                msg = 'Username must contain only characters and numbers!'
            elif not username or not password or not email_address:
                msg = 'Please fill out the form!'
            else:
                # 修正INSERT语句字段与参数的对应关系
                cursor.execute("INSERT INTO user (username, city, email_address, country, password) VALUES (%s, %s, %s, %s, %s)",
                               (username, 'Washington', email_address, 'USA', password))
                mysql.connection.commit()
                msg = 'You have successfully registered!'
        else:
            # 表单为空的情况
            msg = 'Please fill out the form!'
    
    return render_template('register.html', msg=msg)

关键修复点

  • 作用域修正:将数据库操作和变量使用限制在POST请求的分支内,避免GET请求时访问未定义的变量。
  • 变量初始化:在register函数内初始化username、password、email_address为空字符串,彻底避免未定义错误。
  • 缩进修正:把所有表单验证和数据库操作代码放在request.method == 'POST'的分支内,确保只有提交表单时才执行。
  • SQL语句修正:原INSERT语句的字段数量和传入参数数量不匹配,已调整为对应关系(若user_id是自增主键则无需手动插入)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:45:25