variable is undefined flask mysql - python

I need to greet user on the page. F.ex: Hello {{ name }}, but I get the error UnboundLocalError: local variable 'account' referenced before assignment. What is the problem in the code below?
python:
app = Flask(__name__)
mysql = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
cur = mysql.connection.cursor()
cur.execute('INSERT INTO users(name, email) VALUES(%s, %s)', (name, email))
mysql.connection.commit()
cur.close()
return redirect('profile')
return render_template('index.html')
#app.route('/profile', methods=['GET'])
def profile():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
cur = mysql.connection.cursor()
cur.execute('SELECT * FROM users')
account = cur.fetchone()
return render_template('profile.html', account=account)
index.html:
<form action="" method="POST">
<span style="color: #fff;">Firstname:</span><input type="text" name="name" placeholder="Type your firstname"><br><br>
<input type="submit" name="submit" value="submit">
</form>
profile.html
<h4 style="color: #fff;">Your firstname: is {{ account['name'] }}</h4>
<h4 style="color: #fff;">Your email: is {{ account['email'] }}</h4>
I can connect to database and fetch users data, but on the profile.html page I get the error
How to solve it? Please help.

You haven't passed the account to the template.
Instead of ,
return render_template('profile.html')
you need to write as,
return render_template('profile.html', account=account)
EDIT:
#app.route('/profile', methods=['GET','POST'])
def profile():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
cur = mysql.connection.cursor()
cur.execute('SELECT * FROM users')
account = cur.fetchone()
return render_template('profile.html', account=account)
Or if you wanted the profile to be a get request you can do this
#app.route('/profile', methods=['GET','POST'])
def profile():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
cur = mysql.connection.cursor()
cur.execute('SELECT * FROM users')
account = cur.fetchone()
return render_template('profile.html', account=account)

Related

Display username in base.html in Flask

I want to add current username in base.html, but I can't understand how make it.
I have got username, which takes from MySQL database
#app/routes
#app.route('/auth', methods=['GET', 'POST'])
def auth():
msg = ''
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
username = request.form['username']
hash = request.form['password']
salt = b'$2b$12$Mw/92Q0HkYKTR.0.ghNQs.'
password = bytes(hash, encoding='utf-8')
hash_1 = bcrypt.hashpw(password,salt)
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM user WHERE username = % s AND password = % s', (username, hash_1,))
account = cursor.fetchone()
if account:
session['loggedin'] = True
session['id'] = account['id']
session['username'] = account['username']
msg = 'Logged in successfully !'
return render_template('index.html', msg=msg)
else:
msg = 'Неверное имя пользователя/пароль !'
return render_template('auth.html', msg=msg)
How can I take the username field and get it to the base.html, when user is Loggined in? I tryed to make it with using documentation, but it doesn`t work.
#base.html
{% if g.username %}
<li><span>{{ g.user['username'] }}</span>
{% else %}
<a class="p-2 text-dark" href="/auth">Авторизация</a>
{% endif %}
I make it
{% if session.loggedin %}
<a class="p-2 text-dark" href="/auth">Привет,{{session.username}} </a>
{% else %}
<a class="p-2 text-dark" href="/auth">Авторизация</a>

SQL database not showing enteries

Im trying to develop a simple blog app. With base that for now only has user_name field and text (besedilo). After i run it it shows no errors. But data is not stored in database and does not display later on.
app.py
from flask import Flask, render_template, request
from flask_mysqldb import MySQL
import yaml
from flask_bootstrap import Bootstrap
app=Flask(__name__)
bootstrap = Bootstrap(app)
db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = db['mysql_host']
app.config['MYSQL_USER'] = db['mysql_user']
app.config['MYSQL_PASSWORD'] = db['mysql_password']
app.config['MYSQL_DB'] = db['mysql_db']
mysql = MySQL(app)
#app.route('/', methods=['GET','POST'])
def index():
if request.method == 'POST':
form = request.form
user_name = form['user_name']
besedilo = form['besedilo']
cur = mysql.connect.cursor()
cur.execute("INSERT INTO post(user_name, besedilo) VALUES(%s, %s)", (user_name, besedilo))
mysql.connection.commit()
return render_template('index.html')
#app.route('/post')
def post():
cur = mysql.connection.cursor()
result_value = cur.execute("SELECT * FROM post")
if result_value > 0:
post = cur.fetchall()
return render_template('post.html', post=post)
if __name__ == '__main__':
app.run(debug=True)
index.html
{% extends 'base.html' %}
{% block content %}
<h1>Hello</h1>
<form method="post">
NAME:<input type="name" name="user_name">
BESEDILO:<input type="text" name="besedilo">
<input type="submit">
</form>
{% endblock %}
</body>
</html>
post.html
{% extends 'base.html' %}
{% block sub_content %}
<table border = 1>
{% for post in posts %}
<tr>
<td>{{post.user_name}}</td>
<td>{{post.besedilo}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
db.yaml
mysql_host: 'localhost'
mysql_user: 'root'
mysql_password: 'xxxxxxxx'
mysql_db: 'my_blog'
What have i missed. I have installed all packages, field names are matching.
Database that i set up (with the following commands):
CREATE DATABASE my_blog;
CREATE TABLE post(user_name varchar(30), besedilo varchar(150));
and inserts for fine: with
INSERT INTO post(user_name, besedilo) VALUES ('Alex', 'i have a job to do');
mysql> SELECT * FROM post;
+-----------+----------------+
| user_name | besedilo |
+-----------+----------------+
| Peter | some text |
| Alex | i have a job |
+-----------+----------------+
1.) UPDATE :
#app.route('/', methods=['GET','POST'])
def index():
if request.method == 'POST':
form = request.form
user_name = form['user_name']
besedilo = form['besedilo']
conn = mysql.connect()
cur = conn.cursor()
cur.execute("INSERT INTO post(user_name, besedilo) VALUES(%s, %s)", (user_name, besedilo))
conn.commit()
return render_template('index.html')
I have strong suspicion that culprit is if result_value>0.
I suppose it's always returns 0 for SELECT * FROM post not matter if rows exists in table.
Excerpts from MySQL Documentation:
The use of mysql_num_rows() depends on whether you use mysql_store_result() or mysql_use_result() to return the result set. If you use mysql_store_result(), mysql_num_rows() may be called immediately. If you use mysql_use_result(), mysql_num_rows() does not return the correct value until all the rows in the result set have been retrieved.
Try to exclude your result_value check and see results:
#app.route('/post')
def post():
cur = mysql.connection.cursor()
cur.execute("SELECT * FROM post")
# if result_value > 0: ## I suppose that line always returns 0
post = cur.fetchall()
return render_template('post.html', post=post)
As for def index() - I'm not sure there is a problem there.
Inform about your progress.

How to avoid the below error in Python Flask

I am using the below 3 html i.e. Index.html , Results.html and Edit.html
and python code file app.py code is also pasted below.
The save to the DB is working fine and when I retrieve the data for editing and click on Submit I am encountering the below error
"_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s' at line 1")"
Index.html
<h1>Welcome</h1>
<br>
<br>
<form method="POST" action="{{ url_for('index') }}">
Name <input type="text" name="name" />
<br>
Email <input type="email" name="email" />
<br>
CRType <select name = "CRType">
<option value = "New">New</option>
<option value = "Old">Old</option>
</select><br>
<input type="submit" value="Submit">
</form>
Results.html
Add CR
<table border = 1>
{% for user in userDetails %}
<tr>
<td> {{user[3]}} </td>
<td> {{user[0]}} </td>
<td> {{user[1]}} </td>
<td> {{user[2]}} </td>
<td> Edit Profile </td>
</tr>
{% endfor %}
</table>
Edit.html
h1>Welcome to Update Zone</h1>
<br>
<br>
<body>
<form method="POST" action="{{ url_for('Edit') }}">
CR_ID <input type="text" name="CR_ID" value = "{{user[0]}}"/>
<br>
Name <input type="text" name="name" value = "{{user[1]}}"/>
<br>
Email <input type="email" name="email" value = "{{user[2]}}"/>
<br>
<br>
<input type="submit" value="Submit">
</body>
</form>
App.PY
from flask import Flask, render_template, request, redirect
from flask_mysqldb import MySQL
# from flask_table import Table, Col, LinkCol
app = Flask(__name__)
# Configure db
#db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
#app.config['MYSQL_PASSWORD'] = 'P#$$w0rd'
app.config['MYSQL_DB'] = 'flaskapp'
mysql = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# Fetch form data
userDetails = request.form
name = userDetails['name']
email = userDetails['email']
CRType = userDetails['CRType']
# CR_ID = userDetails['CR_ID']
cur = mysql.connection.cursor()
# cur.execute("""INSERT INTO users(name, email, CRType) VALUES(%s, %s, % )""",(name, email, CRType)
cur.execute("""INSERT INTO users (name, email, CRType) VALUES (%s, %s, %s)""", (name, email, CRType))
mysql.connection.commit()
cur.close()
return redirect ('/results')
# return redirect('/results')
return render_template('index.html')
#app.route('/results')
def results():
cur = mysql.connection.cursor()
resultValue = cur.execute("SELECT * from users")
if resultValue > 0:
userDetails = cur.fetchall()
# edit = LinkCol('Edit', 'edit', url_kwargs=dict(id='CR_ID'))
return render_template('results.html',userDetails=userDetails)
#app.route('/Edit', methods=['GET', 'POST'])
def Edit():
# request.method == 'GET':
# Fetch form data
# user = request.form
# CR_ID = user['CR_ID']
CR_ID = request.args.get('CR_ID')
name = request.args.get('name')
email = request.args.get('email')
CRType = request.args.get('CRType')
cur = mysql.connection.cursor()
# result= cur.execute("SELECT CR_ID, name, email from users where CR_ID = 1")
result = cur.execute("""SELECT CR_ID, name, email from users where CR_ID = %s""",CR_ID)
# result = cur.execute("Update table users set name=?, email=?, CRType=? where CR_ID = %s", CR_ID)
RV = cur.fetchall()
user = RV[0]
cur.close()
return render_template('Edit.html',user=user)
if __name__ == '__main__':
app.run(debug= True)
Your SQL statements aren't properly formatted. It should be
result = cur.execute("SELECT CR_ID, name, email from users where CR_ID = %s", (CR_ID))

400 Bad Request: KeyError: 'username'

When testing this code i get the error "400 Bad Request: KeyError: 'username'" and i cant figure out why
Here is the code, i am using flask to do this
#app.route('/')
def index():
if 'username' in session:
username = session['username']
return 'Logged in as ' + username + '<br>' + \
"<b><a href = '/logout'>click here to log out</a></b>"
return "You are not logged in <br><a href = '/login'></b>" + \
"click here to log in</b></a>"
#app.route('/login', methods = ['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form action = "" method = "post">
<p><input type = text name = username/></p>
<p><input type = submit value = Login /></p>
</form>
'''
#app.route('/logout')
def logout():
#remove the session from username if it is there
session.pop('username', None)
return redirect(url_for('index'))
You're getting an error because there's no key username, most likely in the request.form object inside the if request.method == 'POST' block. This may be because of the way you're creating the form in HTML. You should put quotes around the field attributes, like:
<form action="" method="post">
<p><input type="text" name="username" /></p>
<p><input type="submit" value="Login"/></p>
</form>

how to add time to html from python method

this is part of a flask application. I would like to get the current time to output anywhere in the form of the html file.
I would like to add the method current_time() in flaskr.py to the anywhere in the from in the attached html file. Thanks!
flaskr.py
import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
from datetime import date
import time
app = Flask(__name__)
app.config.from_object(__name__)
app.config.update(dict(
DATABASE = os.path.join(app.root_path, 'flaskr.db'), ##in real world apps use instance folders for databases instead
SECRET_KEY = 'development key',
USERNAME = 'admin',
PASSWORD = 'default'
))
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
def connect_db():
rv = sqlite3.connect(app.config['DATABASE'])
rv.row_factory = sqlite3.Row
return rv
def get_db():
if not hasattr(g, 'sqlite_db'):
g.sqlite_db = connect_db()
return g.sqlite_db
#app.teardown_appcontext
def close_db(error):
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
def init_db():
db = get_db()
with app.open_resource('schema.sql', mode = 'r') as f:
db.cursor().executescript(f.read())
db.commit()
#app.cli.command('initdb')
def initdb_command():
init_db()
print('initialized the database.')
#app.route('/')
def show_entries():
db = get_db()
cur = db.execute('select title, text from entries order by id desc')
entries = cur.fetchall()
return render_template('show_entries.html', entries=entries)
#app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
db = get_db()
db.execute('insert into entries (title, text) values (?, ?)',
[request.form['title'], request.form['text']])
db.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
#app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error = error)
#app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
def current_time():
return date.today()
show_entries.html
{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method=post class=add-entry>
<dl>
<dt>Title:
<dd><input type=text size=30 name=title>
<dt>Text:
<dd><textarea name=text rows=5 cols=40></textarea>
<dd><input type=submit value=Share>
</dl>
</form>
{% endif %}
<ul class=entries>
{% for entry in entries %}
<li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
{% else %}
<li><em> No entries so far</em>
{% endfor %}
</ul>
{% endblock %}
You can just use datetime.now() method:
from datetime import datetime
...
return render_template(... current_time = datetime.now())
...

Categories

Resources