forked from orbit-oss/flask
Restructured documentation a bit.
This commit is contained in:
parent
fb2d2e446b
commit
26f86b1d49
2 changed files with 214 additions and 9 deletions
|
|
@ -14,6 +14,24 @@ you rather want to dive into all the internal parts of Flask, check out
|
||||||
the :ref:`api` documentation. Common patterns are described in the
|
the :ref:`api` documentation. Common patterns are described in the
|
||||||
:ref:`patterns` section.
|
:ref:`patterns` section.
|
||||||
|
|
||||||
|
Flask also depends on two external libraries: the `Jinja2`_ template
|
||||||
|
engine and the `Werkzeug`_ WSGI toolkit. both of which are not documented
|
||||||
|
here. If you want to dive into their documentation check out the
|
||||||
|
following links:
|
||||||
|
|
||||||
|
- `Jinja2 Documentation <http://jinja.pocoo.org/2/documentation/>`_
|
||||||
|
- `Werkzeug Documentation <http://werkzeug.pocoo.org/documentation/>`_
|
||||||
|
|
||||||
|
.. _Jinja2: http://jinja.pocoo.org/2/
|
||||||
|
.. _Werkzeug: http://werkzeug.pocoo.org/
|
||||||
|
|
||||||
|
Textual Documentation
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This part of the documentation is written text and should give you an idea
|
||||||
|
how to work with Flask. It's a series of step-by-step instructions for
|
||||||
|
web development.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
|
@ -21,8 +39,18 @@ the :ref:`api` documentation. Common patterns are described in the
|
||||||
installation
|
installation
|
||||||
quickstart
|
quickstart
|
||||||
tutorial
|
tutorial
|
||||||
patterns
|
|
||||||
api
|
|
||||||
deploying
|
|
||||||
testing
|
testing
|
||||||
|
patterns
|
||||||
|
deploying
|
||||||
becomingbig
|
becomingbig
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---------
|
||||||
|
|
||||||
|
If you are looking for information on a specific function, class or
|
||||||
|
method, this part of the documentation is for you:
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
api
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.. _patterns:
|
.. _patterns:
|
||||||
|
|
||||||
Patterns in Flask
|
Patterns for Flask
|
||||||
=================
|
==================
|
||||||
|
|
||||||
Certain things are common enough that the changes are high you will find
|
Certain things are common enough that the changes are high you will find
|
||||||
them in most web applications. For example quite a lot of applications
|
them in most web applications. For example quite a lot of applications
|
||||||
|
|
@ -10,10 +10,93 @@ changes are they will open a database connection at the beginning of the
|
||||||
request and get the information of the currently logged in user. At the
|
request and get the information of the currently logged in user. At the
|
||||||
end of the request, the database connection is closed again.
|
end of the request, the database connection is closed again.
|
||||||
|
|
||||||
In Flask you can implement such things with the
|
|
||||||
:meth:`~flask.Flask.before_request` and
|
.. _larger-applications:
|
||||||
:meth:`~flask.Flask.after_request` decorators in combination with the
|
|
||||||
special :class:`~flask.g` object.
|
Larger Applications
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
For larger applications it's a good idea to use a package instead of a
|
||||||
|
module. That is quite simple. Imagine a small application looks like
|
||||||
|
this::
|
||||||
|
|
||||||
|
/yourapplication
|
||||||
|
/yourapplication.py
|
||||||
|
/static
|
||||||
|
/style.css
|
||||||
|
/templates
|
||||||
|
layout.html
|
||||||
|
index.html
|
||||||
|
login.html
|
||||||
|
...
|
||||||
|
|
||||||
|
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
|
||||||
|
all `.pyc` files first, otherwise things would most likely break)
|
||||||
|
|
||||||
|
You should then end up with something like that::
|
||||||
|
|
||||||
|
/yourapplication
|
||||||
|
/yourapplication
|
||||||
|
/__init__.py
|
||||||
|
/static
|
||||||
|
/style.css
|
||||||
|
/templates
|
||||||
|
layout.html
|
||||||
|
index.html
|
||||||
|
login.html
|
||||||
|
...
|
||||||
|
|
||||||
|
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
|
||||||
|
`yourapplication` folder with the following contents::
|
||||||
|
|
||||||
|
from yourapplication import app
|
||||||
|
app.run(debug=True)
|
||||||
|
|
||||||
|
What did we gain from this? Now we can restructure the application a bit
|
||||||
|
into multiple modules. The only thing you have to remember is the
|
||||||
|
following quick checklist:
|
||||||
|
|
||||||
|
1. the `Flask` application object creation have to be in the
|
||||||
|
`__init__.py` file. That way each module can import it safely and the
|
||||||
|
`__name__` variable will resole to the correct package.
|
||||||
|
2. all the view functions (the ones with a :meth:`~flask.Flask.route`
|
||||||
|
decorator on top) have to be imported when in the `__init__.py` file.
|
||||||
|
Not the objects itself, but the module it is in. Do the importing at
|
||||||
|
the *bottom* of the file.
|
||||||
|
|
||||||
|
Here an example `__init__.py`::
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
import yourapplication.views
|
||||||
|
|
||||||
|
And this is what `views.py` would look like::
|
||||||
|
|
||||||
|
from yourapplication import app
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return 'Hello World!'
|
||||||
|
|
||||||
|
.. admonition:: Circular Imports
|
||||||
|
|
||||||
|
Every Python programmer hates it, and yet we just did that: circular
|
||||||
|
imports (That's when one module depends on another one. In this case
|
||||||
|
`views.py` depends on `__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
|
||||||
|
ensuring the module is imported and we are doing that at the bottom of
|
||||||
|
the file.
|
||||||
|
|
||||||
|
There are still some problems with that approach but if you want to use
|
||||||
|
decorators there is no way around that. Check out the
|
||||||
|
:ref:`becomingbig` section for some inspiration how to deal with that.
|
||||||
|
|
||||||
|
|
||||||
.. _database-pattern:
|
.. _database-pattern:
|
||||||
|
|
@ -21,6 +104,11 @@ special :class:`~flask.g` object.
|
||||||
Using SQLite 3 with Flask
|
Using SQLite 3 with Flask
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
In Flask you can implement opening of dabase connections at the beginning
|
||||||
|
of the request and closing at the end with the
|
||||||
|
:meth:`~flask.Flask.before_request` and :meth:`~flask.Flask.after_request`
|
||||||
|
decorators in combination with the special :class:`~flask.g` object.
|
||||||
|
|
||||||
So here a simple example how you can use SQLite 3 with Flask::
|
So here a simple example how you can use SQLite 3 with Flask::
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
@ -99,6 +187,95 @@ You can then create such a database from the python shell:
|
||||||
>>> from yourapplication import init_db
|
>>> from yourapplication import init_db
|
||||||
>>> init_db()
|
>>> init_db()
|
||||||
|
|
||||||
|
|
||||||
|
.. _sqlalchemy-pattern:
|
||||||
|
|
||||||
|
SQLAlchemy in Flask
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Many people prefer `SQLAlchemy`_ for database access. In this case it's
|
||||||
|
encouraged to use a package instead of a module for your flask application
|
||||||
|
and drop the modules into a separate module (:ref:`larger-applications`).
|
||||||
|
Although that is not necessary but makes a lot of sense.
|
||||||
|
|
||||||
|
There are three very common ways to use SQLAlchemy. I will outline each
|
||||||
|
of them here:
|
||||||
|
|
||||||
|
Declarative
|
||||||
|
```````````
|
||||||
|
|
||||||
|
The declarative extension in SQLAlchemy is the most recent method of using
|
||||||
|
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::
|
||||||
|
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
|
engine = create_engine('sqlite:////tmp/test.db')
|
||||||
|
db_session = scoped_session(sessionmaker(autocommit=False,
|
||||||
|
autoflush=False,
|
||||||
|
bind=engine))
|
||||||
|
Base = declarative_base()
|
||||||
|
Base.query = db_session.query_property()
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
Base.metadata.create_all(bind=engine)
|
||||||
|
|
||||||
|
To define your models, subclass the `Base` class the above code generated.
|
||||||
|
|
||||||
|
To use SQLAlchemy in a declarative way with your application, you just
|
||||||
|
have to put the following code into your application module Flask will
|
||||||
|
automatically remove database sessions at the end of the request for you::
|
||||||
|
|
||||||
|
from yourapplication.database import db_session
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def shutdown_session(response):
|
||||||
|
db_session.remove()
|
||||||
|
return response
|
||||||
|
|
||||||
|
Here an example model (put that into `models.py` for instance)::
|
||||||
|
|
||||||
|
from sqlalchemy import Column, Integer, String
|
||||||
|
from yourapplication.database import Base
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'users'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(50), unique=True)
|
||||||
|
email = Column(String(120), unique=True)
|
||||||
|
|
||||||
|
def __init__(self, name=None, email=None):
|
||||||
|
self.name = name
|
||||||
|
self.email = email
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<User %r>' % (self.name, self.email)
|
||||||
|
|
||||||
|
You can insert entries into the database like this then:
|
||||||
|
|
||||||
|
>>> from yourapplication.database import db_session
|
||||||
|
>>> from yourapplication.models import User
|
||||||
|
>>> u = User('admin', 'admin@localhost')
|
||||||
|
>>> db_session.add(u)
|
||||||
|
>>> db_session.commit()
|
||||||
|
|
||||||
|
Querying is simple as well:
|
||||||
|
|
||||||
|
>>> User.query.all()
|
||||||
|
[<User u'admin'>]
|
||||||
|
>>> User.query.filter(User.name == 'admin').first()
|
||||||
|
<User u'admin'>
|
||||||
|
|
||||||
|
.. _SQLAlchemy: http://www.sqlalchemy.org/
|
||||||
|
.. _declarative:
|
||||||
|
http://www.sqlalchemy.org/docs/reference/ext/declarative.html
|
||||||
|
|
||||||
|
|
||||||
.. _template-inheritance:
|
.. _template-inheritance:
|
||||||
|
|
||||||
Template Inheritance
|
Template Inheritance
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue