Unnecessary brackets being placed around {{name}} when variable is used in HTML (Python Flask Application)

Issue

I am creating a Python Flask application where the name of the user’s account is being passed from a MySQL database into a Flask application where it can be used on webpages.

I’ve successfully been able to retrieve the first name from the user’s credentials in the database using this:

if sha256_crypt.verify(userDetails['password'], str (data[0])):
    cursor.execute("SELECT fname FROM user_details WHERE email = %s;", (email, ))
    name = cursor.fetchone()
    session['user'] = name
    return redirect(url_for('success', name=name))

To explain what this snippet does, once the user’s entered login details have been checked against the database and authorised, the query pulls the first name from the user_details table and assigns it to the name variable, to which the name is used to initiate a session.

The user is then returned to the login page (now logged in) where another variable called name (I will probably change this so it’s easier to differentiate) is passed the name that is stored in the session to display on the website using this function:

@app.route('/loginpage', methods=['POST', 'GET'])
def loginpage():
    if 'user' in session:
        name = session['user']
        return render_template('login.html', name=name, loggedOut=False, loggedIn=True)
    return render_template('login.html', loggedOut=True, loggedIn=False)

This is all successfully working and retrieves the user’s first name from the database, the only problem though is that when the name is displayed with {{name}} in the HTML, the name shows up as (‘John’,), which means for example this:

<div class="container logout-greeting">
    <h5 style="text-align: center">Hello {{name}}, it appears you are logged in, click here to log out</h5>
</div>

Which should display as:

"Hello John, it appears you are logged in, click here to log out"

Is instead displaying as:

"Hello (‘John,’), it appears you are logged in, click here to log out"

I’ve checked with someone that is more experienced with building Web Applications and they couldn’t spot the issue, so is it possible anyone else could give me a pointer as to what is causing this?

Solution

cursor.fetchone() returns all the selected fields from one row as a tuple. For example, if you did something like SELECT first, last ..., you’d get a 2-tuple ("John", "Smith").

You only requested one field, so you get 1-tuple ("John",): you do not get a string "John"! Change to:

name = cursor.fetchone()[0]

EDIT: Or, as Vincent warns below, more robustly:

row = cursor.fetchone()
name = row[0] if row else None

See How to create a tuple with only one element for discussion of 1-tuples, and why there is a comma there.

Answered By – Amadan

Answer Checked By – Marilyn (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.