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:

  1. import datetime
  2. from flask import Flask
  3. from peewee import *
  4. from playhouse.flask_utils import FlaskDB
  5.  
  6. DATABASE = 'postgresql://postgres:password@localhost:5432/my_database'
  7.  
  8. app = Flask(__name__)
  9. app.config.from_object(__name__)
  10.  
  11. db_wrapper = FlaskDB(app)
  12.  
  13. class User(db_wrapper.Model):
  14. username = CharField(unique=True)
  15.  
  16. class Tweet(db_wrapper.Model):
  17. user = ForeignKeyField(User, backref='tweets')
  18. content = TextField()
  19. 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:

  1. # Obtain a reference to the Peewee database instance.
  2. peewee_db = db_wrapper.database
  3.  
  4. @app.route('/transfer-funds/', methods=['POST'])
  5. def transfer_funds():
  6. with peewee_db.atomic():
  7. # ...
  8.  
  9. 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:

  1. app = Flask(__name__)
  2. 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:

  1. DATABASE = {
  2. 'name': 'my_app_db',
  3. 'engine': 'playhouse.pool.PooledPostgresqlDatabase',
  4. 'user': 'postgres',
  5. 'max_connections': 32,
  6. 'stale_timeout': 600,
  7. }
  8.  
  9. app = Flask(__name__)
  10. app.config.from_object(__name__)
  11.  
  12. wrapper = FlaskDB(app)
  13. pooled_postgres_db = wrapper.database

Using a peewee Database object:

  1. peewee_db = PostgresqlExtDatabase('my_app')
  2. app = Flask(__name__)
  3. 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:

  1. db_wrapper = FlaskDB()
  2.  
  3. # Even though the database is not yet initialized, you can still use the
  4. # `Model` property to create model classes.
  5. class User(db_wrapper.Model):
  6. username = CharField(unique=True)
  7.  
  8.  
  9. def create_app():
  10. app = Flask(__name__)
  11. app.config['DATABASE'] = 'sqlite:////home/code/apps/my-database.db'
  12. db_wrapper.init_app(app)
  13. return app

Query utilities

The flask_utils module provides several helpers for managing queries in your web app. Some common patterns include:

  • getobject_or_404(_query_or_model, *query)

Parameters:

  • query_or_model – Either a Model class or a pre-filtered SelectQuery.
  • 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:

  1. @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 is True 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:

  1. @app.route('/blog/')def post_index(): public_posts = (Post .select() .where(Post.published == True) .order_by(Post.timestamp.desc()))

  2. return object_list(
  3.     &#39;post_index.html&#39;,
  4.     query=public_posts,
  5.     context_variable=&#39;post_list&#39;,
  6.     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 the page GET parameter.
  • pagination, a PaginatedQuery instance.
  • class PaginatedQuery(query_or_model, paginate_by[, page_var='page'[, check_bounds=False]])

Parameters:

  • query_or_model – Either a Model or a SelectQuery 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 is True 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 thepage_var GET parameter. If no page is explicitly selected, thenthis method will return 1, indicating the first page.

  • get_page_count()

  • Return the total number of possible pages.

  • get_object_list()

  • Using the value of get_page(), return the pageof objects requested by the user. The return value is aSelectQuery with the appropriate LIMIT and OFFSETclauses.

If check_bounds was set to True and the requested page containsno objects, then a 404 will be raised.