Toggle navigation

Step 6: The View Functions

Now that the database connections are working, you can start writing the view functions. You will need four of them; Show Entries, Add New Entry, Login and Logout. Add the following code snipets to flaskr.py.

Show Entries

This view shows all the entries stored in the database. It listens on the root of the application and will select title and text from the database. The one with the highest id (the newest entry) will be on top. The rows returned from the cursor look a bit like dictionaries because we are using the sqlite3.Row row factory.

The view function will pass the entries to the show_entries.html template and return the rendered one:

@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)

Add New Entry

This view lets the user add new entries if they are logged in. This only responds to POST requests; the actual form is shown on the [UNKNOWN NODE title_reference] page. If everything worked out well, it will flash() an information message to the next request and redirect back to the [UNKNOWN NODE title_reference] page:

@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'))

Note that this view checks that the user is logged in (that is, if the [UNKNOWN NODE title_reference] key is present in the session and True).

Login and Logout

These functions are used to sign the user in and out. Login checks the username and password against the ones from the configuration and sets the [UNKNOWN NODE title_reference] key for the session. If the user logged in successfully, that key is set to True, and the user is redirected back to the [UNKNOWN NODE title_reference] page. In addition, a message is flashed that informs the user that he or she was logged in successfully. If an error occurred, the template is notified about that, and the user is asked again:

@app.route('/login', methods=['GET', 'POST'])
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)

The [UNKNOWN NODE title_reference] function, on the other hand, removes that key from the session again. There is a neat trick here: if you use the pop() method of the dict and pass a second parameter to it (the default), the method will delete the key from the dictionary if present or do nothing when that key is not in there. This is helpful because now it is not necessary to check if the user was logged in.

@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    flash('You were logged out')
    return redirect(url_for('show_entries'))

Continue with Step 7: The Templates.