mirror of https://github.com/mitsuhiko/flask.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
3.5 KiB
87 lines
3.5 KiB
Step 5: The View Functions |
|
========================== |
|
|
|
Now that the database connections are working we can start writing the |
|
view functions. We will need four of them: |
|
|
|
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) on top. The rows returned |
|
from the cursor are tuples with the columns ordered like specified in the |
|
select statement. This is good enough for small applications like here, |
|
but you might want to convert them into a dict. If you are interested how |
|
to do that, check out the :ref:`easy-querying` example. |
|
|
|
The view function will pass the entries as dicts to the |
|
`show_entries.html` template and return the rendered one:: |
|
|
|
@app.route('/') |
|
def show_entries(): |
|
cur = g.db.execute('select title, text from entries order by id desc') |
|
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()] |
|
return render_template('show_entries.html', entries=entries) |
|
|
|
Add New Entry |
|
------------- |
|
|
|
This view lets the user add new entries if he's logged in. This only |
|
responds to `POST` requests, the actual form is shown on the |
|
`show_entries` page. If everything worked out well we will |
|
:func:`~flask.flash` an information message to the next request and |
|
redirect back to the `show_entries` page:: |
|
|
|
@app.route('/add', methods=['POST']) |
|
def add_entry(): |
|
if not session.get('logged_in'): |
|
abort(401) |
|
g.db.execute('insert into entries (title, text) values (?, ?)', |
|
[request.form['title'], request.form['text']]) |
|
g.db.commit() |
|
flash('New entry was successfully posted') |
|
return redirect(url_for('show_entries')) |
|
|
|
Note that we check that the user is logged in here (the `logged_in` 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 |
|
`logged_in` key in the session. If the user logged in successfully that |
|
key is set to `True` and the user is redirected back to the `show_entries` |
|
page. In that case also a message is flashed that informs the user he or |
|
she was logged in successfully. If an error occoured the template is |
|
notified about that and the user asked again:: |
|
|
|
@app.route('/login', methods=['GET', 'POST']) |
|
def login(): |
|
error = None |
|
if request.method == 'POST': |
|
if request.form['username'] != USERNAME: |
|
error = 'Invalid username' |
|
elif request.form['password'] != 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 logout function on the other hand removes that key from the session |
|
again. We use a neat trick here: if you use the :meth:`~dict.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 was not in there. This is helpful because we don't have to check in |
|
that case 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'))
|
|
|