Made grammar changes to the Tutorial.
This commit is contained in:
parent
8421c1ea0c
commit
86cc6f9806
10 changed files with 63 additions and 64 deletions
|
|
@ -3,9 +3,9 @@
|
|||
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
|
||||
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.
|
||||
|
||||
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
|
||||
unchanged.
|
||||
|
||||
We store our current database connection on the special :data:`~flask.g`
|
||||
object that flask provides for us. This object stores information for one
|
||||
We store our current database connection in the special :data:`~flask.g`
|
||||
object that Flask provides for us. This object stores information for one
|
||||
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
|
||||
the scenes to ensure it does the right thing.
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Step 3: Creating The Database
|
|||
Flaskr is a database powered application as outlined earlier, and more
|
||||
precisely, an application powered by a relational database system. Such
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
to provide the path to the database there which leaves some place for
|
||||
errors. It's a good idea to add a function that initializes the database
|
||||
for you to the application.
|
||||
installed, which is not necessarily the case on every system. Also, one has
|
||||
to provide the path to the database which leaves some place for
|
||||
errors. It's a good idea to add a function to the application that
|
||||
initializes the database for you.
|
||||
|
||||
If you want to do that, you first have to import the
|
||||
: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
|
||||
first (`__future__` imports must be the very first import)::
|
||||
want to use Python 2.5, it's also necessary to enable the `with` statement
|
||||
(`__future__` imports must be the very first import)::
|
||||
|
||||
from __future__ import with_statement
|
||||
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
|
||||
explicitly tell it to.
|
||||
|
||||
Now it is possible to create a database by starting up a Python shell and
|
||||
importing and calling that function::
|
||||
Now it is possible to create a database by importing and calling that function
|
||||
from within a Python shell::
|
||||
|
||||
>>> from flaskr import init_db
|
||||
>>> init_db()
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ application::
|
|||
/static
|
||||
/templates
|
||||
|
||||
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
|
||||
schema as well as main module in the following steps. The files inside
|
||||
The `flaskr` folder is not a python package but just something where we
|
||||
drop our files. We will then put our database schema and main module
|
||||
directly into this folder in the following steps. The files inside
|
||||
the `static` folder are available to users of the application via `HTTP`.
|
||||
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.
|
||||
|
||||
Continue with :ref:`tutorial-schema`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
simple microblog application. It only supports one user that can create
|
||||
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
|
||||
as database which comes out of the box with Python, so there is nothing
|
||||
features everything you need to get started. We will use Flask along with
|
||||
the SQLite database which is included with Python, so there is nothing
|
||||
else you need.
|
||||
|
||||
If you want the full sourcecode in advance or for comparison, check out
|
||||
|
|
|
|||
|
|
@ -3,25 +3,25 @@
|
|||
Introducing Flaskr
|
||||
==================
|
||||
|
||||
We will call our blogging application flaskr here, feel free to chose a
|
||||
less web-2.0-ish name ;) Basically we want it to do the following things:
|
||||
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:
|
||||
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
We will be using SQLite3 directly for that application because it's good
|
||||
enough for an application of that size. For larger applications however
|
||||
it makes a lot of sense to use `SQLAlchemy`_ that handles database
|
||||
connections in a more intelligent way, allows you to target different
|
||||
relational databases at once and more. You might also want to consider
|
||||
We will be using SQLite3 directly because it's good enough for an application
|
||||
of this size. For larger applications, however, it makes sense to use
|
||||
`SQLAlchemy`_. Advantages of SQLAlchemy include handling database connections
|
||||
in a more intelligent way, allowing you to target different relational
|
||||
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.
|
||||
|
||||
Here a screenshot from the final application:
|
||||
Here is a screenshot from the final application:
|
||||
|
||||
.. image:: ../_static/flaskr.png
|
||||
:align: center
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ the just created `flaskr` folder:
|
|||
);
|
||||
|
||||
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
|
||||
automatically incrementing integer and a primary key, the other two are
|
||||
strings that must not be null.
|
||||
this table has an `id`, a `title`, and a `text` field. The `id` serves as
|
||||
the primary key and is an automatically incrementing integer. The other two
|
||||
fields are strings that must not be null.
|
||||
|
||||
Continue with :ref:`tutorial-setup`.
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@
|
|||
Step 2: Application Setup Code
|
||||
==============================
|
||||
|
||||
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
|
||||
will add the imports we will need as well as the config section. For
|
||||
small applications it's a possibility to drop the configuration directly
|
||||
into the module which we will be doing here. However a cleaner solution
|
||||
would be to create a separate `.ini` or `.py` file and load that or import
|
||||
the values from there.
|
||||
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
|
||||
will add the required imports as well as the config section. For
|
||||
small applications, such as this, the configuration can be dropped directly
|
||||
into the application module. However, a cleaner solution would be to create
|
||||
a separate `.ini` or `.py` file and load that or import 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
|
||||
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
|
||||
of code above. You can also move that into a separate file.
|
||||
defined there. In our case, :meth:`~flask.Config.from_object` finds the
|
||||
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
|
||||
configurable file. This is what :meth:`~flask.Config.from_envvar` can
|
||||
do::
|
||||
configurable file. This is the purpose of :meth:`~flask.Config.from_envvar`::
|
||||
|
||||
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():
|
||||
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::
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
|
||||
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
|
||||
page not found error because we don't have any views yet. But we will
|
||||
focus on that a little later. First we should get the database working.
|
||||
With that out of the way you should be able to start up the application.
|
||||
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. Not to worry,
|
||||
we'll create some views in a bit. But first we should get the database
|
||||
working.
|
||||
|
||||
.. admonition:: Externally Visible Server
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
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
|
||||
templates are using `Jinja2`_ syntax and have autoescaping enabled by
|
||||
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
|
||||
-----------
|
||||
|
||||
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
|
||||
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.
|
||||
|
|
@ -58,7 +58,7 @@ show_entries.html
|
|||
This template extends the `layout.html` template from above to display the
|
||||
messages. Note that the `for` loop iterates over the messages we passed
|
||||
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:
|
||||
|
||||
.. sourcecode:: html+jinja
|
||||
|
|
@ -88,8 +88,7 @@ method:
|
|||
login.html
|
||||
----------
|
||||
|
||||
Finally the login template which basically just displays a form to allow
|
||||
the user to login:
|
||||
Finally, the login template displays a form allowing the user to login:
|
||||
|
||||
.. sourcecode:: html+jinja
|
||||
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ Bonus: Testing the Application
|
|||
Now that you have finished the application and everything works as
|
||||
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
|
||||
example of how to perform unit testing in the :ref:`testing` section of the
|
||||
documentation. Go there to see how easy it is to test Flask applications.
|
||||
|
|
|
|||
|
|
@ -12,10 +12,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) 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.
|
||||
returned from the cursor are tuples with the columns ordered as specified
|
||||
in the select statement. This is good enough for small applications such
|
||||
as flaskr. For larger applications, 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::
|
||||
|
|
@ -30,8 +31,8 @@ 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
|
||||
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::
|
||||
|
||||
|
|
@ -51,8 +52,8 @@ 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.
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue