Merge remote branch 'mitsuhiko/master'

This commit is contained in:
Nick Walker 2010-10-11 19:09:06 -07:00
commit 38262ccac5
84 changed files with 5584 additions and 2003 deletions

View file

@ -52,7 +52,7 @@ The `secret_key` is needed to keep the client-side sessions secure.
Choose that key wisely and as hard to guess and complex as possible. The
debug flag enables or disables the interactive debugger. Never leave
debug mode activated in a production system because it will allow users to
executed code on the server!
execute code on the server!
We also add a method to easily connect to the database specified. That
can be used to open a connection on request and also from the interactive
@ -64,7 +64,7 @@ Python shell or a script. This will come in handy later
return sqlite3.connect(app.config['DATABASE'])
Finally we just add a line to the bottom of the file that fires up the
server if we run that file as standalone application::
server if we want to run that file as a standalone application::
if __name__ == '__main__':
app.run()
@ -76,7 +76,7 @@ focus on that a little later. First we should get the database working.
.. admonition:: Externally Visible Server
Want your server to be publically available? Check out the
Want your server to be publicly available? Check out the
:ref:`externally visible server <public-server>` section for more
information.

View file

@ -4,7 +4,7 @@ Bonus: Testing the Application
==============================
Now that you have finished the application and everything works as
expected, it's probably not a good idea to add automated tests to simplify
expected, it's probably not a bad idea to add automated tests to simplify
modifications in the future. The application above is used as a basic
example of how to perform unittesting in the :ref:`testing` section of the
documentation. Go there to see how easy it is to test Flask applications.

View file

@ -11,11 +11,11 @@ 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 one with the highest id (the newest entry) will be 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 in 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::
@ -48,16 +48,23 @@ redirect back to the `show_entries` page::
Note that we check that the user is logged in here (the `logged_in` key is
present in the session and `True`).
.. admonition:: Security Note
Be sure to use question marks when building SQL statements, as done in the
example above. Otherwise, your app will be vulnerable to SQL injection when
you use string formatting to build SQL statements.
See :ref:`sqlite3` for more.
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::
`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 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():
@ -73,12 +80,12 @@ notified about that and the user asked again::
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
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
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.
key is not in there. This is helpful because now we don't have to check
if the user was logged in.
::