Home > Software engineering >  Making a flask application with mysql and i keep getting NameError
Making a flask application with mysql and i keep getting NameError

Time:08-06

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')
def login():

    # Output message if something goes wrong...

    msg = ''
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
        # Create variables for easy access
        username = request.form['username']
        password = request.form['password']

    # Check if account exists using MySQL
    cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
    cursor.execute('SELECT * FROM user WHERE username = %s AND password = %s', (username, password))
    # Fetch one record and return result
    account = cursor.fetchone()
    # If account exists in accounts table in out database
    if account:
        # Create session data, we can access this data in other routes
        session['loggedin'] = True
        session['id'] = account['id']
        session['username'] = account['username']
        # Redirect to home page
        return 'Logged in successfully!'
    else:
        # Account doesnt exist or username/password incorrect
        msg = 'Incorrect username/password!'
    return render_template('login.html', msg=msg)


@app.route('/register', methods=['GET', 'POST'])
def register():
    global username
    global password
    global email_address

    msg = ''

    # Check if "username", "password" and "email" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:
        # Create variables for easy access

        username = request.form['username']
        password = request.form['password']
        email_address = request.form['email']
    elif request.method == 'POST':
        # Form is empty... (no POST data)
        msg = 'Please fill out the form!'


    # Show registration form with message (if any)
        # Check if account exists using MySQL


    cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
    cursor.execute('SELECT * FROM accounts WHERE username = %s', (username,))
    account = cursor.fetchone()
    # If account exists show error and validation checks
    if account:
        msg = 'Account already exists!'
    elif not re.match(r'[^@] @[^@] \.[^@] '):
        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:
        # Account doesnt exists and the form data is valid, now insert new account into accounts table
        cursor.execute("INSERT INTO user (user_id,username,city,email_address,country,password) VALUES ( %s, %s, %s, %s)",
                       (username, 'Washington', email_address,'USA',password))
        mysql.connection.commit()
        msg = 'You have successfully registered!'

    return render_template('register.html', msg=msg)







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

keep getting namerror and UnboundLocalError. I want to register users and store their info on a mysql database. all the variables keep appearing as not defined. I followed this toturial:https://codeshack.io/login-system-python-flask-mysql/. I am also on a mac. I read that i shoudnt use global for variable but i dont know any alternatives.

CodePudding user response:

Here is a quickfix, give the username and password default values before you go checking for if the method is POST;

username=""
password=""
msg = ""

if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:

Note the word quickfix; I'd probably only suggest it if you don't need it running very very shortly.

I have some questions as to why you are using the global keyword for username and password inside the register method. I can't find any good reason why to do that. We mostly use global to be able to access a variable throughout the continuity of our script. Since your are using Flask, you can store this in flask sessions or even better, store the information in a database and be able to access it later.

Second, I would move the declaration of username and password; together with the rest of the code inside the following if block:

if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:

In fact I would suggest moving everything inside the register method inside the block apart from msg = '' and return render_template. There is nothing inside there that really needs to be outside the block, and most of them require on the output of the form anyway(which is inside the block).

One more thing, your regex check for an email address is missing the actual email to check.

This is how I would organize the block of code inside the register method.

@app.route('/register', methods=['GET', 'POST'])
def register():

    msg = ''

    # Check if "username", "password" and "email" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:
        # Create variables for easy access

        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 exists show error and validation checks
        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:
            # Account doesnt exists and the form data is valid, now insert new account into accounts table
            cursor.execute("INSERT INTO user (user_id,username,city,email_address,country,password) VALUES ( %s, %s, %s, %s)",
                        (username, 'Washington', email_address,'USA',password))
            mysql.connection.commit()
            msg = 'You have successfully registered!'

        

    elif request.method == 'POST':
        # Form is empty... (no POST data)
        msg = 'Please fill out the form!'

    # Show registration form with message (if any)
    # Check if account exists using MySQL
    return render_template('register.html', msg=msg)

Not in a position of testing everything out; but give it a shot and let me know how it goes. I will do complete tests once I'm in a position to, just posting this in case it is something urgent.

All the best troubleshooting :)

  • Related