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 >
<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?
CodePudding user response:
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.
CodePudding user response:
cursor.fetchone() returns a tuple (similar to a list) containing all columns of the row. Its string representation looks like this.
You can solve this by selecting the first item in the response:
values = cursor.fetchone()
if values:
name = values[0]