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
问题根源
- 变量作用域错误:
login函数中,username和password仅在POST请求的if分支内定义,分支外执行数据库查询时会找不到变量。register函数中,使用global声明完全没必要,且当请求为GET或POST参数不全时,username等变量未被赋值,后续执行数据库操作时触发错误。
- 代码逻辑缩进错误:部分数据库操作和验证代码未放在正确的条件分支内,导致非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
相关产品推荐
相关产品推荐

