Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/tutorial/css.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.. _tutorial-css:

Step 7: Adding Style
Step 9: Adding Style
====================

Now that everything else works, it's time to add some style to the
application. Just create a stylesheet called :file:`style.css` in the
:file:`static` folder we created before:
:file:`static` folder:

.. sourcecode:: css

Expand Down
28 changes: 13 additions & 15 deletions docs/tutorial/dbcon.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
.. _tutorial-dbcon:

Step 3: Database Connections
Step 4: Database Connections
----------------------------

We have created a function for establishing a database connection with
`connect_db`, but by itself, that's not particularly useful. Creating and
closing database connections all the time is very inefficient, so we want
to keep it around for longer. Because database connections encapsulate a
transaction, we also need to make sure that only one request at the time
uses the connection. How can we elegantly do that with Flask?
You now have a function for establishing a database connection with
`connect_db`, but by itself, it is not particularly useful. Creating and
closing database connections all the time is very inefficient, so you will
need to keep it around for longer. Because database connections
encapsulate a transaction, you will need to make sure that only one
request at a time uses the connection. An elegant way to do this is by
utilizing the *application context*.

This is where the application context comes into play, so let's start
there.

Flask provides us with two contexts: the application context and the
request context. For the time being, all you have to know is that there
Flask provides two contexts: the *application context* and the
*request context*. For the time being, all you have to know is that there
are special variables that use these. For instance, the
:data:`~flask.request` variable is the request object associated with
the current request, whereas :data:`~flask.g` is a general purpose
variable associated with the current application context. We will go into
the details of this a bit later.
variable associated with the current application context. The tutorial
will cover some more details of this later on.

For the time being, all you have to know is that you can store information
safely on the :data:`~flask.g` object.
Expand All @@ -37,7 +35,7 @@ already established connection::
g.sqlite_db = connect_db()
return g.sqlite_db

So now we know how to connect, but how do we properly disconnect? For
Now you know how to connect, but how can you properly disconnect? For
that, Flask provides us with the :meth:`~flask.Flask.teardown_appcontext`
decorator. It's executed every time the application context tears down::

Expand Down
29 changes: 15 additions & 14 deletions docs/tutorial/dbinit.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _tutorial-dbinit:

Step 4: Creating The Database
Step 5: Creating The Database
=============================

As outlined earlier, Flaskr is a database powered application, and more
Expand All @@ -16,13 +16,14 @@ Such a schema can be created by piping the ``schema.sql`` file into the

The downside of this is that it requires the ``sqlite3`` command to be
installed, which is not necessarily the case on every system. This also
requires that we provide the path to the database, which can introduce
requires that you provide the path to the database, which can introduce
errors. It's a good idea to add a function that initializes the database
for you to the application.
for you, to the application.

To do this, we can create a function and hook it into the :command:`flask`
command that initializes the database. Let me show you the code first. Just
add this function below the `connect_db` function in :file:`flaskr.py`::
To do this, you can create a function and hook it into a :command:`flask`
command that initializes the database. For now just take a look at the
code segment below. A good place to add this function, and command, is
just below the `connect_db` function in :file:`flaskr.py`::

def init_db():
db = get_db()
Expand All @@ -38,23 +39,23 @@ add this function below the `connect_db` function in :file:`flaskr.py`::

The ``app.cli.command()`` decorator registers a new command with the
:command:`flask` script. When the command executes, Flask will automatically
create an application context for us bound to the right application.
Within the function, we can then access :attr:`flask.g` and other things as
we would expect. When the script ends, the application context tears down
create an application context which is bound to the right application.
Within the function, you can then access :attr:`flask.g` and other things as
you might expect. When the script ends, the application context tears down
and the database connection is released.

We want to keep an actual function around that initializes the database,
You will want to keep an actual function around that initializes the database,
though, so that we can easily create databases in unit tests later on. (For
more information see :ref:`testing`.)

The :func:`~flask.Flask.open_resource` method of the application object
is a convenient helper function that will open a resource that the
application provides. This function opens a file from the resource
location (your ``flaskr`` folder) and allows you to read from it. We are
using this here to execute a script on the database connection.
location (the :file:`flaskr/flaskr` folder) and allows you to read from it.
It is used in this example to execute a script on the database connection.

The connection object provided by SQLite can give us a cursor object.
On that cursor, there is a method to execute a complete script. Finally, we
The connection object provided by SQLite can give you a cursor object.
On that cursor, there is a method to execute a complete script. Finally, you
only have to commit the changes. SQLite3 and other transactional
databases will not commit unless you explicitly tell it to.

Expand Down
26 changes: 15 additions & 11 deletions docs/tutorial/folders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@
Step 0: Creating The Folders
============================

Before we get started, let's create the folders needed for this
Before getting started, you will need to create the folders needed for this
application::

/flaskr
/static
/templates
/flaskr
/static
/templates

The ``flaskr`` folder is not a Python package, but just something where we
drop our files. Later on, we will put our database schema as well as main
module into this folder. It is done in the following way. The files inside
the :file:`static` folder are available to users of the application via HTTP.
This is the place where CSS and Javascript files go. Inside the
:file:`templates` folder, Flask will look for `Jinja2`_ templates. The
templates you create later on in the tutorial will go in this directory.
The application will be installed and run as Python package. This is the
recommended way to install and run Flask applications. You will see exactly
how to run ``flaskr`` later on in this tutorial. For now go ahead and create
the applications directory structure. In the next few steps you will be
creating the database schema as well as the main module.

Continue with :ref:`tutorial-schema`.
As a quick side note, the files inside of the :file:`static` folder are
available to users of the application via HTTP. This is the place where CSS and
Javascript files go. Inside the :file:`templates` folder, Flask will look for
`Jinja2`_ templates. You will see examples of this later on.

For now you should continue with :ref:`tutorial-schema`.

.. _Jinja2: http://jinja.pocoo.org/
1 change: 1 addition & 0 deletions docs/tutorial/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ the `example source`_.
folders
schema
setup
setuptools
dbcon
dbinit
views
Expand Down
9 changes: 5 additions & 4 deletions docs/tutorial/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
Introducing Flaskr
==================

We will call our blogging application Flaskr, but feel free to choose your own
less Web-2.0-ish name ;) Essentially, we want it to do the following things:
This tutorial will demonstrate a blogging application named Flaskr, but feel
free to choose your own less Web-2.0-ish name ;) Essentially, it will do the
following things:

1. Let the user sign in and out with credentials specified in the
configuration. Only one user is supported.
Expand All @@ -14,8 +15,8 @@ less Web-2.0-ish name ;) Essentially, we want it to do the following things:
3. The index page shows all entries so far in reverse chronological order
(newest on top) and the user can add new ones from there if logged in.

We will be using SQLite3 directly for this application because it's good
enough for an application of this size. For larger applications, however,
SQLite3 will be used directly for this application because it's good enough
for an application of this size. For larger applications, however,
it makes a lot of sense to use `SQLAlchemy`_, as it handles database
connections in a more intelligent way, allowing you to target different
relational databases at once and more. You might also want to consider
Expand Down
10 changes: 5 additions & 5 deletions docs/tutorial/schema.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Step 1: Database Schema
=======================

First, we want to create the database schema. Only a single table is needed
for this application and we only want to support SQLite, so creating the
database schema is quite easy. Just put the following contents into a file
named `schema.sql` in the just created `flaskr` folder:
In this step, you will create the database schema. Only a single table is
needed for this application and it will only support SQLite. All you need to do
is put the following contents into a file named :file:`schema.sql` in the
:file:`flaskr/flaskr` folder:

.. sourcecode:: sql

Expand All @@ -17,7 +17,7 @@ named `schema.sql` in the just created `flaskr` folder:
'text' text not null
);

This schema consists of a single table called ``entries``. Each row in
This schema consists of a single table called ``entries``. 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.
Expand Down
73 changes: 26 additions & 47 deletions docs/tutorial/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@
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``. We will place this file inside the ``flaskr``
folder. We will begin by adding the imports we need and by adding the config
section. For small applications, it is possible to drop the configuration
directly into the module, and this is what we will be doing here. However,
a cleaner solution would be to create a separate ``.ini`` or ``.py`` file,
load that, and import the values from there.
Now that the schema is in place, you can create the application module,
:file:`flaskr.py`. This file should be placed inside of the
:file:`flaskr/flaskr` folder. The first several lines of code in the
application module are the needed import statements. After that there will be a
few lines of configuration code. For small applications like ``flaskr``, it is
possible to drop the configuration directly into the module. However, a cleaner
solution is to create a separate ``.ini`` or ``.py`` file, load that, and
import the values from there.

First, we add the imports in :file:`flaskr.py`::
Here are the import statements (in :file:`flaskr.py`)::

# all the imports
import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash

Next, we can create our actual application and initialize it with the
config from the same file in :file:`flaskr.py`::
The next couple lines will create the actual application instance and
initialize it with the config from the same file in :file:`flaskr.py`:

# create our little application :)
app = Flask(__name__)
app.config.from_object(__name__)
.. sourcecode:: python

app = Flask(__name__) # create the application instance :)
app.config.from_object(__name__) # load config from this file , flaskr.py

# Load default config and override config from an environment variable
app.config.update(dict(
Expand All @@ -35,8 +37,8 @@ config from the same file in :file:`flaskr.py`::
))
app.config.from_envvar('FLASKR_SETTINGS', silent=True)

The :class:`~flask.Config` object works similarly to a dictionary so we
can update it with new values.
The :class:`~flask.Config` object works similarly to a dictionary, so it can be
updated with new values.

.. admonition:: Database Path

Expand All @@ -55,10 +57,10 @@ can update it with new values.

Usually, it is a good idea to load a separate, environment-specific
configuration file. Flask allows you to import multiple configurations and it
will use the setting defined in the last import. This enables robust
will use the setting defined in the last import. This enables robust
configuration setups. :meth:`~flask.Config.from_envvar` can help achieve this.

.. code-block:: python
.. sourcecode:: python

app.config.from_envvar('FLASKR_SETTINGS', silent=True)

Expand All @@ -74,45 +76,22 @@ that in all cases, only variable names that are uppercase are considered.
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.

We will also add a method that allows for easy connections to the
specified database. This can be used to open a connection on request and
Lastly, you will add a method that allows for easy connections to the
specified database. This can be used to open a connection on request and
also from the interactive Python shell or a script. This will come in
handy later. We create a simple database connection through SQLite and
handy later. You can create a simple database connection through SQLite and
then tell it to use the :class:`sqlite3.Row` object to represent rows.
This allows us to treat the rows as if they were dictionaries instead of
This allows the rows to be treated as if they were dictionaries instead of
tuples.

::
.. sourcecode:: python

def connect_db():
"""Connects to the specific database."""
rv = sqlite3.connect(app.config['DATABASE'])
rv.row_factory = sqlite3.Row
return rv

With that out of the way, you should be able to start up the application
without problems. Do this with the following commands::

export FLASK_APP=flaskr
export FLASK_DEBUG=1
flask run

(In case you are on Windows you need to use `set` instead of `export`).
The :envvar:`FLASK_DEBUG` flag enables or disables the interactive debugger.
*Never leave debug mode activated in a production system*, because it will
allow users to execute code on the server!

You will see a message telling you that server has started along with
the address at which you can access it.

When you head over to the server in your browser, you will get a 404 error
because we don't have any views yet. We will focus on that a little later,
but first, we should get the database working.

.. admonition:: Externally Visible Server

Want your server to be publicly available? Check out the
:ref:`externally visible server <public-server>` section for more
information.
In the next section you will see how to run the application.

Continue with :ref:`tutorial-dbcon`.
Continue with :ref:`tutorial-setuptools`.
Loading