whenever the application context tears down — that is, roughly speaking, when the
execution of the application is terminated by the user or by an error/exception:
@app.teardown_appcontext
def close_db(error):
”’ Closes the TC database at the end of the request. ”’
if hasattr(g, ‘sqlite_db’):
g.sqlite_db.close()
Core functionality
Building on the database infrastructure, we can now proceed and implement the core
functionality for the application. First, we have to define what happens when we connect
to the main/home page of the application. To this end, we use the Flask function decorator
@app.route(“/”). The function decorated in that way will be called whenever a
connection is established to the main page. The function show_entries basically
establishes a database connection, retrieves all comments posted so far (maybe none,
maybe many), and sends them to a template-based rendering engine to return an HTML
document based on the template and the data provided (more on the templating part soon):
@app.route(‘/’)
def show_entries():
”’ Renders all entries of the TC database. ”’
db = get_db()
query = ‘select comment, user, time from comments order by id desc’
cursor = db.execute(query)
comments = cursor.fetchall()
return render_template(‘show_entries.html’, comments=comments)
We only want to allow registered users to post comments in the chat room. Therefore, we
must provide functionality for a user to register. To this end, technically, we must allow
use of the POST method for the respective HTML to be rendered by the application and to be
accessed by the user. To register, a user must provide a username and a password.
Otherwise, an error is reported. The function register should be considered a simple
illustration only. It is missing a number of ingredients important for real-world
applications, like checking whether a username already exists and encryption of the
passwords (they are stored as plain text). Once users have successfully registered, their
status is automatically changed to logged_in and they are redirected to the main page via
redirect(url_for(“show_entries”)):
@app.route(‘/register’, methods=[‘GET’, ‘POST’])
def register():
”’ Registers a new user in the TC database. ”’
error = None
if request.method == ‘POST’:
db = get_db()
if request.form[‘username’] == ” or request.form[‘password’] == ”:
error = ‘Provide both a username and a password.’
# both fields have to be nonempty
else:
db.execute(‘insert into users (name, password) values (?, ?)’,
[request.form[‘username’], request.form[‘password’]])
db.commit()
session[‘logged_in’] = True
# directly log in new user
flash(‘You were sucessfully registered.’)
app.config.update(dict(USERNAME=request.form[‘username’]))
return redirect(url_for(‘show_entries’))
return render_template(‘register.html’, error=error)
For such a web application, there are probably returning users that do not need or want to
reregister anew. We therefore need to provide a form to log in with an existing account.
This is what the function login does. The functionality is similar to that provided by