Made grammar changes to the Tutorial.

This commit is contained in:
Matthew Rankin 2010-12-30 09:00:56 -06:00
parent 8421c1ea0c
commit 86cc6f9806
10 changed files with 63 additions and 64 deletions

View file

@ -3,9 +3,9 @@
Step 4: Request Database Connections Step 4: Request Database Connections
------------------------------------ ------------------------------------
Now we know how we can open database connections and use them for scripts, Now we know how to open database connections and use them for scripts,
but how can we elegantly do that for requests? We will need the database but how can we elegantly do that for requests? We will need the database
connection in all our functions so it makes sense to initialize them connection in all our functions, so it makes sense to initialize them
before each request and shut them down afterwards. before each request and shut them down afterwards.
Flask allows us to do that with the :meth:`~flask.Flask.before_request` and Flask allows us to do that with the :meth:`~flask.Flask.before_request` and
@ -27,10 +27,10 @@ passed the response that will be sent to the client. They have to return
that response object or a different one. In this case we just return it that response object or a different one. In this case we just return it
unchanged. unchanged.
We store our current database connection on the special :data:`~flask.g` We store our current database connection in the special :data:`~flask.g`
object that flask provides for us. This object stores information for one object that Flask provides for us. This object stores information for one
request only and is available from within each function. Never store such request only and is available from within each function. Never store such
things on other objects because this would not work with threaded things in other objects because this would not work with threaded
environments. That special :data:`~flask.g` object does some magic behind environments. That special :data:`~flask.g` object does some magic behind
the scenes to ensure it does the right thing. the scenes to ensure it does the right thing.

View file

@ -6,7 +6,7 @@ Step 3: Creating The Database
Flaskr is a database powered application as outlined earlier, and more Flaskr is a database powered application as outlined earlier, and more
precisely, an application powered by a relational database system. Such precisely, an application powered by a relational database system. Such
systems need a schema that tells them how to store that information. So systems need a schema that tells them how to store that information. So
before starting the server for the first time it's important to create before starting the server for the first time, it's important to create
that schema. that schema.
Such a schema can be created by piping the `schema.sql` file into the Such a schema can be created by piping the `schema.sql` file into the
@ -15,15 +15,15 @@ Such a schema can be created by piping the `schema.sql` file into the
sqlite3 /tmp/flaskr.db < schema.sql sqlite3 /tmp/flaskr.db < schema.sql
The downside of this is that it requires the sqlite3 command to be The downside of this is that it requires the sqlite3 command to be
installed which is not necessarily the case on every system. Also one has installed, which is not necessarily the case on every system. Also, one has
to provide the path to the database there which leaves some place for to provide the path to the database which leaves some place for
errors. It's a good idea to add a function that initializes the database errors. It's a good idea to add a function to the application that
for you to the application. initializes the database for you.
If you want to do that, you first have to import the If you want to do that, you first have to import the
:func:`contextlib.closing` function from the contextlib package. If you :func:`contextlib.closing` function from the contextlib package. If you
want to use Python 2.5 it's also necessary to enable the `with` statement want to use Python 2.5, it's also necessary to enable the `with` statement
first (`__future__` imports must be the very first import):: (`__future__` imports must be the very first import)::
from __future__ import with_statement from __future__ import with_statement
from contextlib import closing from contextlib import closing
@ -52,8 +52,8 @@ execute a complete script. Finally we only have to commit the changes.
SQLite 3 and other transactional databases will not commit unless you SQLite 3 and other transactional databases will not commit unless you
explicitly tell it to. explicitly tell it to.
Now it is possible to create a database by starting up a Python shell and Now it is possible to create a database by importing and calling that function
importing and calling that function:: from within a Python shell::
>>> from flaskr import init_db >>> from flaskr import init_db
>>> init_db() >>> init_db()

View file

@ -10,12 +10,12 @@ application::
/static /static
/templates /templates
The `flaskr` folder is not a python package, but just something where we The `flaskr` folder is not a python package but just something where we
drop our files. Directly into this folder we will then put our database drop our files. We will then put our database schema and main module
schema as well as main module in the following steps. The files inside directly into this folder in the following steps. The files inside
the `static` folder are available to users of the application via `HTTP`. the `static` folder are available to users of the application via `HTTP`.
This is the place where css and javascript files go. Inside the This is the place where css and javascript files go. Inside the
`templates` folder Flask will look for `Jinja2`_ templates. The `templates` folder, Flask will look for `Jinja2`_ templates. The
templates you create later in the tutorial will go in this directory. templates you create later in the tutorial will go in this directory.
Continue with :ref:`tutorial-schema`. Continue with :ref:`tutorial-schema`.

View file

@ -7,8 +7,8 @@ You want to develop an application with Python and Flask? Here you have
the chance to learn that by example. In this tutorial we will create a the chance to learn that by example. In this tutorial we will create a
simple microblog application. It only supports one user that can create simple microblog application. It only supports one user that can create
text-only entries and there are no feeds or comments, but it still text-only entries and there are no feeds or comments, but it still
features everything you need to get started. We will use Flask and SQLite features everything you need to get started. We will use Flask along with
as database which comes out of the box with Python, so there is nothing the SQLite database which is included with Python, so there is nothing
else you need. else you need.
If you want the full sourcecode in advance or for comparison, check out If you want the full sourcecode in advance or for comparison, check out

View file

@ -3,25 +3,25 @@
Introducing Flaskr Introducing Flaskr
================== ==================
We will call our blogging application flaskr here, feel free to chose a We will call our blogging application flaskr. Feel free to chose a
less web-2.0-ish name ;) Basically we want it to do the following things: less web-2.0-ish name. ;) Basically we want it to do the following things:
1. let the user sign in and out with credentials specified in the 1. Let the user sign in and out with credentials specified in the
configuration. Only one user is supported. configuration. Only one user is supported.
2. when the user is logged in he or she can add new entries to the page 2. When the user is logged in he or she can add new entries to the page
consisting of a text-only title and some HTML for the text. This HTML consisting of a text-only title and some HTML for the text. This HTML
is not sanitized because we trust the user here. is not sanitized because we trust the user here.
3. the page shows all entries so far in reverse order (newest on top) and 3. The page shows all entries so far in reverse order (newest on top) and
the user can add new ones from there if logged in. the user can add new ones from there if logged in.
We will be using SQLite3 directly for that application because it's good We will be using SQLite3 directly because it's good enough for an application
enough for an application of that size. For larger applications however of this size. For larger applications, however, it makes sense to use
it makes a lot of sense to use `SQLAlchemy`_ that handles database `SQLAlchemy`_. Advantages of SQLAlchemy include handling database connections
connections in a more intelligent way, allows you to target different in a more intelligent way, allowing you to target different relational
relational databases at once and more. You might also want to consider databases at once, and more. You might also want to consider
one of the popular NoSQL databases if your data is more suited for those. one of the popular NoSQL databases if your data is more suited for those.
Here a screenshot from the final application: Here is a screenshot from the final application:
.. image:: ../_static/flaskr.png .. image:: ../_static/flaskr.png
:align: center :align: center

View file

@ -18,8 +18,8 @@ the just created `flaskr` folder:
); );
This schema consists of a single table called `entries` and each row in This schema consists of a single table called `entries` and each row in
this table has an `id`, a `title` and a `text`. The `id` is an this table has an `id`, a `title`, and a `text` field. The `id` serves as
automatically incrementing integer and a primary key, the other two are the primary key and is an automatically incrementing integer. The other two
strings that must not be null. fields are strings that must not be null.
Continue with :ref:`tutorial-setup`. Continue with :ref:`tutorial-setup`.

View file

@ -3,13 +3,12 @@
Step 2: Application Setup Code Step 2: Application Setup Code
============================== ==============================
Now that we have the schema in place we can create the application module. Now that we have the schema in place, we can create the application module.
Let's call it `flaskr.py` inside the `flaskr` folder. For starters we Let's call it `flaskr.py` inside the `flaskr` folder. For starters, we
will add the imports we will need as well as the config section. For will add the required imports as well as the config section. For
small applications it's a possibility to drop the configuration directly small applications, such as this, the configuration can be dropped directly
into the module which we will be doing here. However a cleaner solution into the application module. However, a cleaner solution would be to create
would be to create a separate `.ini` or `.py` file and load that or import a separate `.ini` or `.py` file and load that or import the values from there.
the values from there.
:: ::
@ -34,12 +33,11 @@ config from the same file::
:meth:`~flask.Config.from_object` will look at the given object (if it's a :meth:`~flask.Config.from_object` will look at the given object (if it's a
string it will import it) and then look for all uppercase variables string it will import it) and then look for all uppercase variables
defined there. In our case, the configuration we just wrote a few lines defined there. In our case, :meth:`~flask.Config.from_object` finds the
of code above. You can also move that into a separate file. configuration we just wrote a few lines of code above.
It is also a good idea to be able to load a configuration from a It is also a good idea to be able to load a configuration from a
configurable file. This is what :meth:`~flask.Config.from_envvar` can configurable file. This is the purpose of :meth:`~flask.Config.from_envvar`::
do::
app.config.from_envvar('FLASKR_SETTINGS', silent=True) app.config.from_envvar('FLASKR_SETTINGS', silent=True)
@ -63,16 +61,17 @@ Python shell or a script. This will come in handy later.
def connect_db(): def connect_db():
return sqlite3.connect(app.config['DATABASE']) return sqlite3.connect(app.config['DATABASE'])
Finally we just add a line to the bottom of the file that fires up the Finally, we add a line to the bottom of the file that fires up the
server if we want to run that file as a standalone application:: server if we want to run that file as a standalone application::
if __name__ == '__main__': if __name__ == '__main__':
app.run() app.run()
With that out of the way you should be able to start up the application With that out of the way you should be able to start up the application.
without problems. When you head over to the server you will get an 404 When you head over to your web browser you will get a 404
page not found error because we don't have any views yet. But we will page not found error because we don't have any views yet. Not to worry,
focus on that a little later. First we should get the database working. we'll create some views in a bit. But first we should get the database
working.
.. admonition:: Externally Visible Server .. admonition:: Externally Visible Server

View file

@ -3,7 +3,7 @@
Step 6: The Templates Step 6: The Templates
===================== =====================
Now we should start working on the templates. If we request the URLs now Now we should start working on the templates. If we request the URLs now,
we would only get an exception that Flask cannot find the templates. The we would only get an exception that Flask cannot find the templates. The
templates are using `Jinja2`_ syntax and have autoescaping enabled by templates are using `Jinja2`_ syntax and have autoescaping enabled by
default. This means that unless you mark a value in the code with default. This means that unless you mark a value in the code with
@ -21,7 +21,7 @@ Put the following templates into the `templates` folder:
layout.html layout.html
----------- -----------
This template contains the HTML skeleton, the header and a link to log in This template contains the HTML skeleton, the header, and a link to log in
(or log out if the user was already logged in). It also displays the (or log out if the user was already logged in). It also displays the
flashed messages if there are any. The ``{% block body %}`` block can be flashed messages if there are any. The ``{% block body %}`` block can be
replaced by a block of the same name (``body``) in a child template. replaced by a block of the same name (``body``) in a child template.
@ -58,7 +58,7 @@ show_entries.html
This template extends the `layout.html` template from above to display the This template extends the `layout.html` template from above to display the
messages. Note that the `for` loop iterates over the messages we passed messages. Note that the `for` loop iterates over the messages we passed
in with the :func:`~flask.render_template` function. We also tell the in with the :func:`~flask.render_template` function. We also tell the
form to submit to your `add_entry` function and use `POST` as `HTTP` form to submit to the `add_entry` function and use `POST` as `HTTP`
method: method:
.. sourcecode:: html+jinja .. sourcecode:: html+jinja
@ -88,8 +88,7 @@ method:
login.html login.html
---------- ----------
Finally the login template which basically just displays a form to allow Finally, the login template displays a form allowing the user to login:
the user to login:
.. sourcecode:: html+jinja .. sourcecode:: html+jinja

View file

@ -12,10 +12,11 @@ Show Entries
This view shows all the entries stored in the database. It listens on the 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. 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 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 returned from the cursor are tuples with the columns ordered as specified
in the select statement. This is good enough for small applications like in the select statement. This is good enough for small applications such
here, but you might want to convert them into a dict. If you are as flaskr. For larger applications, you might want to convert them into a
interested in how to do that, check out the :ref:`easy-querying` example. 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 The view function will pass the entries as dicts to the
`show_entries.html` template and return the rendered one:: `show_entries.html` template and return the rendered one::
@ -30,8 +31,8 @@ Add New Entry
------------- -------------
This view lets the user add new entries if he's logged in. This only 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 responds to `POST` requests. The actual form is shown on the
`show_entries` page. If everything worked out well we will `show_entries` page. If everything worked out well, we will
:func:`~flask.flash` an information message to the next request and :func:`~flask.flash` an information message to the next request and
redirect back to the `show_entries` page:: redirect back to the `show_entries` page::
@ -51,8 +52,8 @@ present in the session and `True`).
.. admonition:: Security Note .. admonition:: Security Note
Be sure to use question marks when building SQL statements, as done in the 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 example above. Otherwise, your app will be vulnerable to SQL injection
you use string formatting to build SQL statements. when you use string formatting to build SQL statements.
See :ref:`sqlite3` for more. See :ref:`sqlite3` for more.
Login and Logout Login and Logout