Permalink
Browse files

Restructured documentation a bit.

  • Loading branch information...
1 parent fb2d2e4 commit 26f86b1d4954dd7512684130ee803b42eca8d72e @mitsuhiko mitsuhiko committed Apr 16, 2010
Showing with 213 additions and 8 deletions.
  1. +30 −2 docs/index.rst
  2. +183 −6 docs/patterns.rst
View
@@ -14,15 +14,43 @@ you rather want to dive into all the internal parts of Flask, check out
the :ref:`api` documentation. Common patterns are described in the
: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::
:maxdepth: 2
foreword
installation
quickstart
tutorial
+ testing
patterns
- api
deploying
- testing
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
View
@@ -1,7 +1,7 @@
.. _patterns:
-Patterns in Flask
-=================
+Patterns for Flask
+==================
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
@@ -10,17 +10,105 @@ 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
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
-:meth:`~flask.Flask.after_request` decorators in combination with the
-special :class:`~flask.g` object.
+
+.. _larger-applications:
+
+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:
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::
import sqlite3
@@ -99,6 +187,95 @@ You can then create such a database from the python shell:
>>> from yourapplication import 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

0 comments on commit 26f86b1

Please sign in to comment.