Flask Utils
The playhouse.flask_utils
module contains several helpers for integratingpeewee with the Flask web framework.
Database Wrapper
The FlaskDB
class is a wrapper for configuring and referencing aPeewee database from within a Flask application. Don’t let it’s name fool you:it is not the same thing as a peewee database. FlaskDB
is designed toremove the following boilerplate from your flask app:
- Dynamically create a Peewee database instance based on app config data.
- Create a base class from which all your application’s models will descend.
- Register hooks at the start and end of a request to handle opening andclosing a database connection.
Basic usage:
- import datetime
- from flask import Flask
- from peewee import *
- from playhouse.flask_utils import FlaskDB
- DATABASE = 'postgresql://postgres:password@localhost:5432/my_database'
- app = Flask(__name__)
- app.config.from_object(__name__)
- db_wrapper = FlaskDB(app)
- class User(db_wrapper.Model):
- username = CharField(unique=True)
- class Tweet(db_wrapper.Model):
- user = ForeignKeyField(User, backref='tweets')
- content = TextField()
- timestamp = DateTimeField(default=datetime.datetime.now)
The above code example will create and instantiate a peeweePostgresqlDatabase
specified by the given database URL. Requesthooks will be configured to establish a connection when a request is received,and automatically close the connection when the response is sent. Lastly, theFlaskDB
class exposes a FlaskDB.Model
property which canbe used as a base for your application’s models.
Here is how you can access the wrapped Peewee database instance that isconfigured for you by the FlaskDB
wrapper:
- # Obtain a reference to the Peewee database instance.
- peewee_db = db_wrapper.database
- @app.route('/transfer-funds/', methods=['POST'])
- def transfer_funds():
- with peewee_db.atomic():
- # ...
- return jsonify({'transfer-id': xid})
Note
The actual peewee database can be accessed using the FlaskDB.database
attribute.
Here is another way to configure a Peewee database using FlaskDB
:
- app = Flask(__name__)
- db_wrapper = FlaskDB(app, 'sqlite:///my_app.db')
While the above examples show using a database URL, for more advanced usagesyou can specify a dictionary of configuration options, or simply pass in apeewee Database
instance:
- DATABASE = {
- 'name': 'my_app_db',
- 'engine': 'playhouse.pool.PooledPostgresqlDatabase',
- 'user': 'postgres',
- 'max_connections': 32,
- 'stale_timeout': 600,
- }
- app = Flask(__name__)
- app.config.from_object(__name__)
- wrapper = FlaskDB(app)
- pooled_postgres_db = wrapper.database
Using a peewee Database
object:
- peewee_db = PostgresqlExtDatabase('my_app')
- app = Flask(__name__)
- db_wrapper = FlaskDB(app, peewee_db)
Database with Application Factory
If you prefer to use the application factory pattern,the FlaskDB
class implements an init_app()
method.
Using as a factory:
- db_wrapper = FlaskDB()
- # Even though the database is not yet initialized, you can still use the
- # `Model` property to create model classes.
- class User(db_wrapper.Model):
- username = CharField(unique=True)
- def create_app():
- app = Flask(__name__)
- app.config['DATABASE'] = 'sqlite:////home/code/apps/my-database.db'
- db_wrapper.init_app(app)
- return app
Query utilities
The flask_utils
module provides several helpers for managing queries in your web app. Some common patterns include:
Parameters:
- query_or_model – Either a
Model
class or a pre-filteredSelectQuery
. - query – An arbitrarily complex peewee expression.
Retrieve the object matching the given query, or return a 404 not foundresponse. A common use-case might be a detail page for a weblog. You wantto either retrieve the post matching the given URL, or return a 404.
Example:
- @app.route('/blog/<slug>/')def post_detail(slug): public_posts = Post.select().where(Post.published == True) post = get_object_or_404(public_posts, (Post.slug == slug)) return render_template('post_detail.html', post=post)
objectlist
(_template_name, query[, context_variable='object_list'[, paginate_by=20[, page_var='page'[, check_bounds=True[, **kwargs]]]]])
Parameters:
- template_name – The name of the template to render.
- query – A
SelectQuery
instance to paginate. - context_variable – The context variable name to use for the paginated object list.
- paginate_by – Number of objects per-page.
- page_var – The name of the
GET
argument which contains the page. - check_bounds – Whether to check that the given page is a valid page. If
check_bounds
isTrue
and an invalid page is specified, then a 404 will be returned. - kwargs – Arbitrary key/value pairs to pass into the template context.
Retrieve a paginated list of objects specified by the given query. Thepaginated object list will be dropped into the context using the givencontext_variable
, as well as metadata about the current page and totalnumber of pages, and finally any arbitrary context data passed askeyword-arguments.
The page is specified using the page
GET
argument, e.g./my-object-list/?page=3
would return the third page of objects.
Example:
- @app.route('/blog/')def post_index(): public_posts = (Post .select() .where(Post.published == True) .order_by(Post.timestamp.desc()))
return object_list(
'post_index.html',
query=public_posts,
context_variable='post_list',
paginate_by=10)
The template will have the following context:
post_list
, which contains a list of up to 10 posts.page
, which contains the current page based on the value of thepage
GET
parameter.pagination
, aPaginatedQuery
instance.
Parameters:
- query_or_model – Either a
Model
or aSelectQuery
instance containing the collection of records you wish to paginate. - paginate_by – Number of objects per-page.
- page_var – The name of the
GET
argument which contains the page. - check_bounds – Whether to check that the given page is a valid page. If
check_bounds
isTrue
and an invalid page is specified, then a 404 will be returned.
Helper class to perform pagination based on GET
arguments.
get_page
()Return the currently selected page, as indicated by the value of the
page_var
GET
parameter. If no page is explicitly selected, thenthis method will return 1, indicating the first page.Return the total number of possible pages.
- Using the value of
get_page()
, return the pageof objects requested by the user. The return value is aSelectQuery
with the appropriateLIMIT
andOFFSET
clauses.
If check_bounds
was set to True
and the requested page containsno objects, then a 404 will be raised.