forked from orbit-oss/flask
Minor edits to tutorial for clarity. (#2330)
This commit is contained in:
parent
471c7f3220
commit
50c6df7098
8 changed files with 103 additions and 85 deletions
|
|
@ -3,6 +3,9 @@
|
||||||
Step 4: Database Connections
|
Step 4: Database Connections
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
Let's continue building our code in the ``flaskr.py`` file.
|
||||||
|
(Scroll to the end of the page for more about project layout.)
|
||||||
|
|
||||||
You currently have a function for establishing a database connection with
|
You currently have a function for establishing a database connection with
|
||||||
`connect_db`, but by itself, it is not particularly useful. Creating and
|
`connect_db`, but by itself, it is not particularly useful. Creating and
|
||||||
closing database connections all the time is very inefficient, so you will
|
closing database connections all the time is very inefficient, so you will
|
||||||
|
|
|
||||||
|
|
@ -9,31 +9,37 @@ systems need a schema that tells them how to store that information.
|
||||||
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 could be created by piping the ``schema.sql`` file into the
|
||||||
`sqlite3` command as follows::
|
``sqlite3`` command as follows::
|
||||||
|
|
||||||
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
|
However, the downside of this is that it requires the ``sqlite3`` command
|
||||||
installed, which is not necessarily the case on every system. This also
|
to be installed, which is not necessarily the case on every system. This
|
||||||
requires that you provide the path to the database, which can introduce
|
also 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
|
errors.
|
||||||
for you, to the application.
|
|
||||||
|
|
||||||
To do this, you can create a function and hook it into a :command:`flask`
|
Instead of the ``sqlite3`` command above, it's a good idea to add a function
|
||||||
command that initializes the database. For now just take a look at the
|
to our application that initializes the database for you. To do this, you
|
||||||
code segment below. A good place to add this function, and command, is
|
can create a function and hook it into a :command:`flask` command that
|
||||||
just below the `connect_db` function in :file:`flaskr.py`::
|
initializes the database.
|
||||||
|
|
||||||
|
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():
|
def init_db():
|
||||||
db = get_db()
|
db = get_db()
|
||||||
|
|
||||||
with app.open_resource('schema.sql', mode='r') as f:
|
with app.open_resource('schema.sql', mode='r') as f:
|
||||||
db.cursor().executescript(f.read())
|
db.cursor().executescript(f.read())
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@app.cli.command('initdb')
|
@app.cli.command('initdb')
|
||||||
def initdb_command():
|
def initdb_command():
|
||||||
"""Initializes the database."""
|
"""Initializes the database."""
|
||||||
|
|
||||||
init_db()
|
init_db()
|
||||||
print('Initialized the database.')
|
print('Initialized the database.')
|
||||||
|
|
||||||
|
|
@ -59,7 +65,8 @@ On that cursor, there is a method to execute a complete script. Finally, you
|
||||||
only have to commit the changes. SQLite3 and other transactional
|
only have to commit the changes. SQLite3 and other transactional
|
||||||
databases will not commit unless you explicitly tell it to.
|
databases will not commit unless you explicitly tell it to.
|
||||||
|
|
||||||
Now, it is possible to create a database with the :command:`flask` script::
|
Now, in a terminal, from the application root directory :file:`flaskr/` it is
|
||||||
|
possible to create a database with the :command:`flask` script::
|
||||||
|
|
||||||
flask initdb
|
flask initdb
|
||||||
Initialized the database.
|
Initialized the database.
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@
|
||||||
Step 0: Creating The Folders
|
Step 0: Creating The Folders
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Before getting started, you will need to create the folders needed for this
|
It is recommended to install your Flask application within a virtualenv. Please
|
||||||
application::
|
read the :ref:`installation` section to set up your environment.
|
||||||
|
|
||||||
|
Now that you have installed Flask, you will need to create the folders required
|
||||||
|
for this tutorial. Your directory structure will look like this::
|
||||||
|
|
||||||
/flaskr
|
/flaskr
|
||||||
/flaskr
|
/flaskr
|
||||||
|
|
@ -13,9 +16,10 @@ application::
|
||||||
|
|
||||||
The application will be installed and run as Python package. This is the
|
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
|
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
|
how to run ``flaskr`` later on in this tutorial.
|
||||||
the applications directory structure. In the next few steps you will be
|
|
||||||
creating the database schema as well as the main module.
|
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.
|
||||||
|
|
||||||
As a quick side note, the files inside of the :file:`static` folder are
|
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
|
available to users of the application via HTTP. This is the place where CSS and
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,19 @@
|
||||||
Tutorial
|
Tutorial
|
||||||
========
|
========
|
||||||
|
|
||||||
You want to develop an application with Python and Flask? Here you have
|
Learn by example to develop an application with Python and Flask.
|
||||||
the chance to learn by example. In this tutorial, we will create a simple
|
|
||||||
microblogging application. It only supports one user that can create
|
In this tutorial, we will create a simple blogging application. It only
|
||||||
text-only entries and there are no feeds or comments, but it still
|
supports one user, only allows text entries, and has no feeds or comments.
|
||||||
features everything you need to get started. We will use Flask and SQLite
|
|
||||||
as a database (which comes out of the box with Python) so there is nothing
|
While very simple, this example still features everything you need to get
|
||||||
else you need.
|
started. In addition to Flask, we will use SQLite for the database, which is
|
||||||
|
built-in to Python, so there is nothing else you need.
|
||||||
|
|
||||||
If you want the full source code in advance or for comparison, check out
|
If you want the full source code in advance or for comparison, check out
|
||||||
the `example source`_.
|
the `example source`_.
|
||||||
|
|
||||||
.. _example source:
|
.. _example source: https://github.com/pallets/flask/tree/master/examples/flaskr/
|
||||||
https://github.com/pallets/flask/tree/master/examples/flaskr/
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ tutorial you will see exactly how to extend the ``flask`` command line
|
||||||
interface (CLI).
|
interface (CLI).
|
||||||
|
|
||||||
A useful pattern to manage a Flask application is to install your app
|
A useful pattern to manage a Flask application is to install your app
|
||||||
following the `Python Packaging Guide`_. Presently this involves
|
following the `Python Packaging Guide`_. Presently this involves
|
||||||
creating two new files; :file:`setup.py` and :file:`MANIFEST.in` in the
|
creating two new files; :file:`setup.py` and :file:`MANIFEST.in` in the
|
||||||
projects root directory. You also need to add an :file:`__init__.py`
|
projects root directory. You also need to add an :file:`__init__.py`
|
||||||
file to make the :file:`flaskr/flaskr` directory a package. After these
|
file to make the :file:`flaskr/flaskr` directory a package. After these
|
||||||
changes, your code structure should be::
|
changes, your code structure should be::
|
||||||
|
|
||||||
/flaskr
|
/flaskr
|
||||||
|
|
@ -25,9 +25,7 @@ changes, your code structure should be::
|
||||||
setup.py
|
setup.py
|
||||||
MANIFEST.in
|
MANIFEST.in
|
||||||
|
|
||||||
The content of the ``setup.py`` file for ``flaskr`` is:
|
Create the ``setup.py`` file for ``flaskr`` with the following content::
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
|
|
@ -43,53 +41,53 @@ The content of the ``setup.py`` file for ``flaskr`` is:
|
||||||
When using setuptools, it is also necessary to specify any special files
|
When using setuptools, it is also necessary to specify any special files
|
||||||
that should be included in your package (in the :file:`MANIFEST.in`).
|
that should be included in your package (in the :file:`MANIFEST.in`).
|
||||||
In this case, the static and templates directories need to be included,
|
In this case, the static and templates directories need to be included,
|
||||||
as well as the schema. Create the :file:`MANIFEST.in` and add the
|
as well as the schema.
|
||||||
following lines::
|
|
||||||
|
Create the :file:`MANIFEST.in` and add the following lines::
|
||||||
|
|
||||||
graft flaskr/templates
|
graft flaskr/templates
|
||||||
graft flaskr/static
|
graft flaskr/static
|
||||||
include flaskr/schema.sql
|
include flaskr/schema.sql
|
||||||
|
|
||||||
To simplify locating the application, add the following import statement
|
Next, to simplify locating the application, create the file,
|
||||||
into this file, :file:`flaskr/__init__.py`:
|
:file:`flaskr/__init__.py` containing only the following import statement::
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
from .flaskr import app
|
from .flaskr import app
|
||||||
|
|
||||||
This import statement brings the application instance into the top-level
|
This import statement brings the application instance into the top-level
|
||||||
of the application package. When it is time to run the application, the
|
of the application package. When it is time to run the application, the
|
||||||
Flask development server needs the location of the app instance. This
|
Flask development server needs the location of the app instance. This
|
||||||
import statement simplifies the location process. Without it the export
|
import statement simplifies the location process. Without the above
|
||||||
statement a few steps below would need to be
|
import statement, the export statement a few steps below would need to be
|
||||||
``export FLASK_APP=flaskr.flaskr``.
|
``export FLASK_APP=flaskr.flaskr``.
|
||||||
|
|
||||||
At this point you should be able to install the application. As usual, it
|
At this point you should be able to install the application. As usual, it
|
||||||
is recommended to install your Flask application within a `virtualenv`_.
|
is recommended to install your Flask application within a `virtualenv`_.
|
||||||
With that said, go ahead and install the application with::
|
With that said, from the ``flaskr/`` directory, go ahead and install the
|
||||||
|
application with::
|
||||||
|
|
||||||
pip install --editable .
|
pip install --editable .
|
||||||
|
|
||||||
The above installation command assumes that it is run within the projects
|
The above installation command assumes that it is run within the projects
|
||||||
root directory, `flaskr/`. The `editable` flag allows editing
|
root directory, ``flaskr/``. The ``editable`` flag allows editing
|
||||||
source code without having to reinstall the Flask app each time you make
|
source code without having to reinstall the Flask app each time you make
|
||||||
changes. The flaskr app is now installed in your virtualenv (see output
|
changes. The flaskr app is now installed in your virtualenv (see output
|
||||||
of ``pip freeze``).
|
of ``pip freeze``).
|
||||||
|
|
||||||
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.
|
||||||
Do this with the following commands::
|
Do this on Mac or Linux with the following commands in ``flaskr/``::
|
||||||
|
|
||||||
export FLASK_APP=flaskr
|
export FLASK_APP=flaskr
|
||||||
export FLASK_DEBUG=true
|
export FLASK_DEBUG=true
|
||||||
flask run
|
flask run
|
||||||
|
|
||||||
(In case you are on Windows you need to use `set` instead of `export`).
|
(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.
|
The :envvar:`FLASK_DEBUG` flag enables or disables the interactive debugger.
|
||||||
*Never leave debug mode activated in a production system*, because it will
|
*Never leave debug mode activated in a production system*, because it will
|
||||||
allow users to execute code on the server!
|
allow users to execute code on the server!
|
||||||
|
|
||||||
You will see a message telling you that server has started along with
|
You will see a message telling you that server has started along with
|
||||||
the address at which you can access it.
|
the address at which you can access it in a browser.
|
||||||
|
|
||||||
When you head over to the server in your browser, you will get a 404 error
|
When you head over to the server in your browser, you will get a 404 error
|
||||||
because we don't have any views yet. That will be addressed a little later,
|
because we don't have any views yet. That will be addressed a little later,
|
||||||
|
|
|
||||||
|
|
@ -3,27 +3,31 @@
|
||||||
Step 2: Application Setup Code
|
Step 2: Application Setup Code
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Now that the schema is in place, you can create the application module,
|
Next, we will create the application module, :file:`flaskr.py`. Just like the
|
||||||
:file:`flaskr.py`. This file should be placed inside of the
|
:file:`schema.sql` file you created in the previous step, this file should be
|
||||||
:file:`flaskr/flaskr` folder. The first several lines of code in the
|
placed inside of the :file:`flaskr/flaskr` folder.
|
||||||
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
|
For this tutorial, all the Python code we use will be put into this file
|
||||||
possible to drop the configuration directly into the module. However, a cleaner
|
(except for one line in ``__init__.py``, and any testing or optional files you
|
||||||
solution is to create a separate ``.ini`` or ``.py`` file, load that, and
|
decide to create).
|
||||||
import the values from there.
|
|
||||||
|
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
|
||||||
|
``.py`` file, load that, and import the values from there.
|
||||||
|
|
||||||
Here are the import statements (in :file:`flaskr.py`)::
|
Here are the import statements (in :file:`flaskr.py`)::
|
||||||
|
|
||||||
# all the imports
|
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from flask import Flask, request, session, g, redirect, url_for, abort, \
|
|
||||||
render_template, flash
|
from flask import (Flask, request, session, g, redirect, url_for, abort,
|
||||||
|
render_template, flash)
|
||||||
|
|
||||||
The next couple lines will create the actual application instance and
|
The next couple lines will create the actual application instance and
|
||||||
initialize it with the config from the same file in :file:`flaskr.py`:
|
initialize it with the config from the same file in :file:`flaskr.py`::
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
app = Flask(__name__) # create the application instance :)
|
app = Flask(__name__) # create the application instance :)
|
||||||
app.config.from_object(__name__) # load config from this file , flaskr.py
|
app.config.from_object(__name__) # load config from this file , flaskr.py
|
||||||
|
|
@ -37,8 +41,8 @@ initialize it with the config from the same file in :file:`flaskr.py`:
|
||||||
))
|
))
|
||||||
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
|
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
|
||||||
|
|
||||||
The :class:`~flask.Config` object works similarly to a dictionary, so it can be
|
In the above code, the :class:`~flask.Config` object works similarly to a
|
||||||
updated with new values.
|
dictionary, so it can be updated with new values.
|
||||||
|
|
||||||
.. admonition:: Database Path
|
.. admonition:: Database Path
|
||||||
|
|
||||||
|
|
@ -58,15 +62,15 @@ updated with new values.
|
||||||
Usually, it is a good idea to load a separate, environment-specific
|
Usually, it is a good idea to load a separate, environment-specific
|
||||||
configuration file. Flask allows you to import multiple configurations and it
|
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.
|
configuration setups. :meth:`~flask.Config.from_envvar` can help achieve
|
||||||
|
this. ::
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
|
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
|
||||||
|
|
||||||
Simply define the environment variable :envvar:`FLASKR_SETTINGS` that points to
|
If you want to do this (not required for this tutorial) simply define the
|
||||||
a config file to be loaded. The silent switch just tells Flask to not complain
|
environment variable :envvar:`FLASKR_SETTINGS` that points to a config file
|
||||||
if no such environment key is set.
|
to be loaded. The silent switch just tells Flask to not complain if no such
|
||||||
|
environment key is set.
|
||||||
|
|
||||||
In addition to that, you can use the :meth:`~flask.Config.from_object`
|
In addition to that, you can use the :meth:`~flask.Config.from_object`
|
||||||
method on the config object and provide it with an import name of a
|
method on the config object and provide it with an import name of a
|
||||||
|
|
@ -76,22 +80,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.
|
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.
|
Choose that key wisely and as hard to guess and complex as possible.
|
||||||
|
|
||||||
Lastly, you will add a method that allows for easy connections to the
|
Lastly, add a method that allows for easy connections to the specified
|
||||||
specified database. This can be used to open a connection on request and
|
database. ::
|
||||||
also from the interactive Python shell or a script. This will come in
|
|
||||||
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 the rows to be treated as if they were dictionaries instead of
|
|
||||||
tuples.
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
def connect_db():
|
def connect_db():
|
||||||
"""Connects to the specific database."""
|
"""Connects to the specific database."""
|
||||||
|
|
||||||
rv = sqlite3.connect(app.config['DATABASE'])
|
rv = sqlite3.connect(app.config['DATABASE'])
|
||||||
rv.row_factory = sqlite3.Row
|
rv.row_factory = sqlite3.Row
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
the rows to be treated as if they were dictionaries instead of tuples.
|
||||||
|
|
||||||
In the next section you will see how to run the application.
|
In the next section you will see how to run the application.
|
||||||
|
|
||||||
Continue with :ref:`tutorial-packaging`.
|
Continue with :ref:`tutorial-packaging`.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ escaped with their XML equivalents.
|
||||||
We are also using template inheritance which makes it possible to reuse
|
We are also using template inheritance which makes it possible to reuse
|
||||||
the layout of the website in all pages.
|
the layout of the website in all pages.
|
||||||
|
|
||||||
Put the following templates into the :file:`templates` folder:
|
Create the follwing three HTML files and place them in the
|
||||||
|
:file:`templates` folder:
|
||||||
|
|
||||||
.. _Jinja2: http://jinja.pocoo.org/docs/templates
|
.. _Jinja2: http://jinja.pocoo.org/docs/templates
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ Step 6: The View Functions
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
Now that the database connections are working, you can start writing the
|
Now that the database connections are working, you can start writing the
|
||||||
view functions. You will need four of them:
|
view functions. You will need four of them; Show Entries, Add New Entry,
|
||||||
|
Login and Logout. Add the following code snipets to :file:`flaskr.py`.
|
||||||
|
|
||||||
Show Entries
|
Show Entries
|
||||||
------------
|
------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue