forked from orbit-oss/flask
docs: :file:app.py, :file:yourapp/templates
This commit is contained in:
parent
3fa4fd0908
commit
a8f570cc62
32 changed files with 93 additions and 93 deletions
|
|
@ -60,9 +60,9 @@ Factories & Extensions
|
|||
It's preferable to create your extensions and app factories so that the
|
||||
extension object does not initially get bound to the application.
|
||||
|
||||
Using `Flask-SQLAlchemy <http://pythonhosted.org/Flask-SQLAlchemy/>`_,
|
||||
Using `Flask-SQLAlchemy <http://pythonhosted.org/Flask-SQLAlchemy/>`_,
|
||||
as an example, you should not do something along those lines::
|
||||
|
||||
|
||||
def create_app(config_filename):
|
||||
app = Flask(__name__)
|
||||
app.config.from_pyfile(config_filename)
|
||||
|
|
@ -72,7 +72,7 @@ as an example, you should not do something along those lines::
|
|||
But, rather, in model.py (or equivalent)::
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
|
||||
and in your application.py (or equivalent)::
|
||||
|
||||
def create_app(config_filename):
|
||||
|
|
@ -83,7 +83,7 @@ and in your application.py (or equivalent)::
|
|||
db.init_app(app)
|
||||
|
||||
Using this design pattern, no application-specific state is stored on the
|
||||
extension object, so one extension object can be used for multiple apps.
|
||||
extension object, so one extension object can be used for multiple apps.
|
||||
For more information about the design of extensions refer to :doc:`/extensiondev`.
|
||||
|
||||
Using Applications
|
||||
|
|
@ -91,7 +91,7 @@ Using Applications
|
|||
|
||||
So to use such an application you then have to create the application
|
||||
first in a separate file otherwise the ``flask`` command won't be able
|
||||
to find it. Here an example `exampleapp.py` file that creates such
|
||||
to find it. Here an example :file:`exampleapp.py` file that creates such
|
||||
an application::
|
||||
|
||||
from yourapplication import create_app
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ Flask itself, and all the libraries you can find on the cheeseshop
|
|||
are distributed with either distribute, the older setuptools or distutils.
|
||||
|
||||
In this case we assume your application is called
|
||||
`yourapplication.py` and you are not using a module, but a :ref:`package
|
||||
:file:`yourapplication.py` and you are not using a module, but a :ref:`package
|
||||
<larger-applications>`. Distributing resources with standard modules is
|
||||
not supported by `distribute`_ so we will not bother with it. If you have
|
||||
not yet converted your application into a package, head over to the
|
||||
|
|
@ -42,13 +42,13 @@ Basic Setup Script
|
|||
|
||||
Because you have Flask running, you either have setuptools or distribute
|
||||
available on your system anyways. If you do not, fear not, there is a
|
||||
script to install it for you: `distribute_setup.py`_. Just download and
|
||||
script to install it for you: :file:`distribute_setup.py`_. Just download and
|
||||
run with your Python interpreter.
|
||||
|
||||
Standard disclaimer applies: :ref:`you better use a virtualenv
|
||||
<virtualenv>`.
|
||||
|
||||
Your setup code always goes into a file named `setup.py` next to your
|
||||
Your setup code always goes into a file named :file:`setup.py` next to your
|
||||
application. The name of the file is only convention, but because
|
||||
everybody will look for a file with that name, you better not change it.
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ Yes, even if you are using `distribute`, you are importing from a package
|
|||
called `setuptools`. `distribute` is fully backwards compatible with
|
||||
`setuptools`, so it also uses the same import name.
|
||||
|
||||
A basic `setup.py` file for a Flask application looks like this::
|
||||
A basic :file:`setup.py` file for a Flask application looks like this::
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ the `find_packages` function::
|
|||
|
||||
Most parameters to the `setup` function should be self explanatory,
|
||||
`include_package_data` and `zip_safe` might not be.
|
||||
`include_package_data` tells distribute to look for a `MANIFEST.in` file
|
||||
`include_package_data` tells distribute to look for a :file:`MANIFEST.in` file
|
||||
and install all the entries that match as package data. We will use this
|
||||
to distribute the static files and templates along with the Python module
|
||||
(see :ref:`distributing-resources`). The `zip_safe` flag can be used to
|
||||
|
|
@ -98,16 +98,16 @@ Distributing Resources
|
|||
----------------------
|
||||
|
||||
If you try to install the package you just created, you will notice that
|
||||
folders like `static` or `templates` are not installed for you. The
|
||||
folders like :file:`static` or :file:`templates` are not installed for you. The
|
||||
reason for this is that distribute does not know which files to add for
|
||||
you. What you should do, is to create a `MANIFEST.in` file next to your
|
||||
`setup.py` file. This file lists all the files that should be added to
|
||||
you. What you should do, is to create a :file:`MANIFEST.in` file next to your
|
||||
:file:`setup.py` file. This file lists all the files that should be added to
|
||||
your tarball::
|
||||
|
||||
recursive-include yourapplication/templates *
|
||||
recursive-include yourapplication/static *
|
||||
|
||||
Don't forget that even if you enlist them in your `MANIFEST.in` file, they
|
||||
Don't forget that even if you enlist them in your :file:`MANIFEST.in` file, they
|
||||
won't be installed for you unless you set the `include_package_data`
|
||||
parameter of the `setup` function to ``True``!
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ Installing / Developing
|
|||
-----------------------
|
||||
|
||||
To install your application (ideally into a virtualenv) just run the
|
||||
`setup.py` script with the `install` parameter. It will install your
|
||||
:file:`setup.py` script with the `install` parameter. It will install your
|
||||
application into the virtualenv's site-packages folder and also download
|
||||
and install all dependencies::
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ upfront:
|
|||
- Fabric 1.0 has to be installed locally. This tutorial assumes the
|
||||
latest version of Fabric.
|
||||
- The application already has to be a package and requires a working
|
||||
`setup.py` file (:ref:`distribute-deployment`).
|
||||
:file:`setup.py` file (:ref:`distribute-deployment`).
|
||||
- In the following example we are using `mod_wsgi` for the remote
|
||||
servers. You can of course use your own favourite server there, but
|
||||
for this example we chose Apache + `mod_wsgi` because it's very easy
|
||||
|
|
@ -25,7 +25,7 @@ upfront:
|
|||
Creating the first Fabfile
|
||||
--------------------------
|
||||
|
||||
A fabfile is what controls what Fabric executes. It is named `fabfile.py`
|
||||
A fabfile is what controls what Fabric executes. It is named :file:`fabfile.py`
|
||||
and executed by the `fab` command. All the functions defined in that file
|
||||
will show up as `fab` subcommands. They are executed on one or more
|
||||
hosts. These hosts can be defined either in the fabfile or on the command
|
||||
|
|
@ -168,7 +168,7 @@ can pack up the application and deploy it::
|
|||
Fabric will now connect to all servers and run the commands as written
|
||||
down in the fabfile. First it will execute pack so that we have our
|
||||
tarball ready and then it will execute deploy and upload the source code
|
||||
to all servers and install it there. Thanks to the `setup.py` file we
|
||||
to all servers and install it there. Thanks to the :file:`setup.py` file we
|
||||
will automatically pull in the required libraries into our virtual
|
||||
environment.
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ So here is a full example::
|
|||
return redirect(url_for('index'))
|
||||
return render_template('login.html', error=error)
|
||||
|
||||
And here the ``layout.html`` template which does the magic:
|
||||
And here the :file:`layout.html` template which does the magic:
|
||||
|
||||
.. sourcecode:: html+jinja
|
||||
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ special error reporting in that case.
|
|||
The HTML
|
||||
--------
|
||||
|
||||
Your index.html template either has to extend a `layout.html` template with
|
||||
Your index.html template either has to extend a :file:`layout.html` template with
|
||||
jQuery loaded and the `$SCRIPT_ROOT` variable set, or do that on the top.
|
||||
Here's the HTML code needed for our little application (`index.html`).
|
||||
Here's the HTML code needed for our little application (:file:`index.html`).
|
||||
Notice that we also drop the script directly into the HTML here. It is
|
||||
usually a better idea to have that in a separate script file:
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Imagine the current application looks somewhat like this::
|
|||
pass
|
||||
|
||||
Then the centralized approach you would have one file with the views
|
||||
(`views.py`) but without any decorator::
|
||||
(:file:`views.py`) but without any decorator::
|
||||
|
||||
def index():
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Declarative
|
|||
The default behavior of MongoKit is the declarative one that is based on
|
||||
common ideas from Django or the SQLAlchemy declarative extension.
|
||||
|
||||
Here an example `app.py` module for your application::
|
||||
Here an example :file:`app.py` module for your application::
|
||||
|
||||
from flask import Flask
|
||||
from mongokit import Connection, Document
|
||||
|
|
@ -47,7 +47,7 @@ MongoDB is schemaless. This means you can modify the data structure from one
|
|||
insert query to the next without any problem. MongoKit is just schemaless
|
||||
too, but implements some validation to ensure data integrity.
|
||||
|
||||
Here is an example document (put this also into `app.py`, e.g.)::
|
||||
Here is an example document (put this also into :file:`app.py`, e.g.)::
|
||||
|
||||
def max_length(length):
|
||||
def validate(value):
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Simple Packages
|
|||
|
||||
To convert that into a larger one, just create a new folder
|
||||
`yourapplication` inside the existing one and move everything below it.
|
||||
Then rename `yourapplication.py` to `__init__.py`. (Make sure to delete
|
||||
Then rename :file:`yourapplication.py` to :file:`__init__.py`. (Make sure to delete
|
||||
all `.pyc` files first, otherwise things would most likely break)
|
||||
|
||||
You should then end up with something like that::
|
||||
|
|
@ -41,7 +41,7 @@ You should then end up with something like that::
|
|||
But how do you run your application now? The naive ``python
|
||||
yourapplication/__init__.py`` will not work. Let's just say that Python
|
||||
does not want modules in packages to be the startup file. But that is not
|
||||
a big problem, just add a new file called `runserver.py` next to the inner
|
||||
a big problem, just add a new file called :file:`runserver.py` next to the inner
|
||||
`yourapplication` folder with the following contents::
|
||||
|
||||
from yourapplication import app
|
||||
|
|
@ -52,21 +52,21 @@ into multiple modules. The only thing you have to remember is the
|
|||
following quick checklist:
|
||||
|
||||
1. the `Flask` application object creation has to be in the
|
||||
`__init__.py` file. That way each module can import it safely and the
|
||||
:file:`__init__.py` file. That way each module can import it safely and the
|
||||
`__name__` variable will resolve to the correct package.
|
||||
2. all the view functions (the ones with a :meth:`~flask.Flask.route`
|
||||
decorator on top) have to be imported in the `__init__.py` file.
|
||||
decorator on top) have to be imported in the :file:`__init__.py` file.
|
||||
Not the object itself, but the module it is in. Import the view module
|
||||
**after the application object is created**.
|
||||
|
||||
Here's an example `__init__.py`::
|
||||
Here's an example :file:`__init__.py`::
|
||||
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
import yourapplication.views
|
||||
|
||||
And this is what `views.py` would look like::
|
||||
And this is what :file:`views.py` would look like::
|
||||
|
||||
from yourapplication import app
|
||||
|
||||
|
|
@ -93,9 +93,9 @@ You should then end up with something like that::
|
|||
|
||||
Every Python programmer hates them, and yet we just added some:
|
||||
circular imports (That's when two modules depend on each other. In this
|
||||
case `views.py` depends on `__init__.py`). Be advised that this is a
|
||||
case :file:`views.py` depends on :file:`__init__.py`). Be advised that this is a
|
||||
bad idea in general but here it is actually fine. The reason for this is
|
||||
that we are not actually using the views in `__init__.py` and just
|
||||
that we are not actually using the views in :file:`__init__.py` and just
|
||||
ensuring the module is imported and we are doing that at the bottom of
|
||||
the file.
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ SQLAlchemy. It allows you to define tables and models in one go, similar
|
|||
to how Django works. In addition to the following text I recommend the
|
||||
official documentation on the `declarative`_ extension.
|
||||
|
||||
Here the example `database.py` module for your application::
|
||||
Here the example :file:`database.py` module for your application::
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
|
|
@ -70,7 +70,7 @@ when the application shuts down::
|
|||
def shutdown_session(exception=None):
|
||||
db_session.remove()
|
||||
|
||||
Here is an example model (put this into `models.py`, e.g.)::
|
||||
Here is an example model (put this into :file:`models.py`, e.g.)::
|
||||
|
||||
from sqlalchemy import Column, Integer, String
|
||||
from yourapplication.database import Base
|
||||
|
|
@ -122,7 +122,7 @@ flexible but a little more to type. In general it works like the
|
|||
declarative approach, so make sure to also split up your application into
|
||||
multiple modules in a package.
|
||||
|
||||
Here is an example `database.py` module for your application::
|
||||
Here is an example :file:`database.py` module for your application::
|
||||
|
||||
from sqlalchemy import create_engine, MetaData
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
|
|
@ -145,7 +145,7 @@ application module::
|
|||
def shutdown_session(exception=None):
|
||||
db_session.remove()
|
||||
|
||||
Here is an example table and model (put this into `models.py`)::
|
||||
Here is an example table and model (put this into :file:`models.py`)::
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String
|
||||
from sqlalchemy.orm import mapper
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ with an example.
|
|||
Base Template
|
||||
-------------
|
||||
|
||||
This template, which we'll call ``layout.html``, defines a simple HTML skeleton
|
||||
This template, which we'll call :file:`layout.html`, defines a simple HTML skeleton
|
||||
document that you might use for a simple two-column page. It's the job of
|
||||
"child" templates to fill the empty blocks with content:
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ how easy this is. WTForms does half the form generation for us already.
|
|||
To make it even nicer, we can write a macro that renders a field with
|
||||
label and a list of errors if there are any.
|
||||
|
||||
Here's an example `_formhelpers.html` template with such a macro:
|
||||
Here's an example :file:`_formhelpers.html` template with such a macro:
|
||||
|
||||
.. sourcecode:: html+jinja
|
||||
|
||||
|
|
@ -102,8 +102,8 @@ the input element. Note that WTForms returns standard Python unicode
|
|||
strings, so we have to tell Jinja2 that this data is already HTML escaped
|
||||
with the `|safe` filter.
|
||||
|
||||
Here the `register.html` template for the function we used above which
|
||||
takes advantage of the `_formhelpers.html` template:
|
||||
Here the :file:`register.html` template for the function we used above which
|
||||
takes advantage of the :file:`_formhelpers.html` template:
|
||||
|
||||
.. sourcecode:: html+jinja
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue