Flask-Validates

Painless form validation using view decorators.

Installation

Using pip:

pip install Flask-Validates

Usage

Flask-Validates binds forms to views using the validates() decorator, depending on how you use it Flask-Validates can eliminate the need entirely to create explicit form classes. When a view is invoked validates() creates a form behind the scenes based on the fields you provide which is then exposed to the view via current_form which works in a similar manner to Flask’s flask.current_app.

Alongside creating forms validates() also sets the appropriate HTTP 400 response code if form validation fails.

The following example demonstrates using validates() to validate three form fields:

from flask_validates import current_form, validates

@app.route("/register", methods=["GET", "POST"])
@validates(
    first_name=StringField(validators=[DataRequired()],
    last_name=StringField(validators=[DataRequired()],
    email=StringField(validators=[DataRequired, Email()]
)
def register():
    if request.method == "POST" and current_form.validate():
        create_user()
        return redirect(url_for("index"))
    return render_template("register.html.j2")

It’s also possible to use existing forms with validates() as is happening in the following example:

from flask_validates import current_form, validates

class RegistrationForm(Form):
    first_name = StringField(validators=[DataRequired()]
    last_name = StringField(validators=[DataRequired()]
    email = StringField(validators=[DataRequired, Email()]

@app.route("/register", methods=["GET", "POST"])
@validates(RegistrationForm)
def register():
    if request.method == "POST" and current_form.validate():
        create_user()
        return redirect(url_for("index"))
    return render_template("register.html.j2")

In some cases you might want to add additional fields to a more generic form. The validates() decorator supports this by allowing both a form class and fields to be specified at the same time:

from flask_validates import current_form, validates

class SimpleRegistrationForm(Form):
    first_name = StringField(validators=[DataRequired()]
    last_name = StringField(validators=[DataRequired()]
    email = StringField(validators=[DataRequired, Email()]

@app.route("/register", methods=["GET", "POST"])
@validates(SimpleRegistrationForm, captcha=Captcha())
def register():
    if request.method == "POST" and current_form.validate():
        create_user()
        return redirect(url_for("index"))
    return render_template("register.html.j2")

Populating form objects

Quite often you’ll want to populate an existing form with your own data, for instance when rendering a form for an edit page. With WTForms this can be done by passing an object to the form constructor. In Flask-Validates the same behaviour can be achieved by calling populate() on current_form as is done in the following example:

from flask_validates import current_form, validates

@app.route("/items/<id>/edit", methods=["GET", "POST"])
@validates(ItemForm)
def edit(id):
    item = get_item(id)
    if request.method == "POST" and current_form.validate():
        update_item()
        return redirect(url_for("index"))
    return render_template("edit_item.html.j2",
                           form=current_form.populate(item))

Usage with Flask-WTF

Flask-WTF is a popular extension that makes working with Flask and WTForms a bit nicer. Flask-Validates can be configured to work with Flask-WTF as follows:

from flask_wtf import FlaskForm
from flask_validates import FlaskValidates

app = Flask(__name__)
FlaskValidates(app, FlaskForm)

API

class flask_validates.FlaskValidates(app=None, form_cls=None)
init_app(app, form_cls=None)

Initializes FlaskValidates with given app.

The default form class used by FlaskValidates can be overridden by specifying form_cls.

flask_validates.current_form

Points to the form created by validates().

flask_validates.validates(form_cls=None, **fields)

Adds form validation to a Flask view.

form_cls specifies the base class on which validation is performed including any fields that might be present. If form_cls is not specified it defaults to wtforms.Form or the form class passed to FlaskValidates if set.

fields specifies the fields that are to be added to form_cls.

class flask_validates.validates.PopulateMixin
populate(obj=None, data=None, **kwargs)

Populates form with the given values and returns the form instance.

If obj is provided it is checked for attributes matching form field names, which will be used for form field values.

data accepts a dictionary of data and is only used if obj is not present.

**kwargs accepts arbitrary values for attributes not found on obj.