Creating Forms

This part of the documentation covers the Form parts.

Secure Form

Without any configuration, the Form will be a session secure form with csrf protection. We encourage you do nothing.

But if you want to disable the csrf protection, you can pass:

form = Form(csrf_enabled=False)

If you want to disable it globally, which you really shouldn’t. But if you insist, it can be done with the configuration:


In order to generate the csrf token, you must have a secret key, this is usually the same as your Flask app secret key. If you want to use another secret key, config it:

WTF_CSRF_SECRET_KEY = 'a random string'

File Uploads

Flask-WTF provides you a FileField to handle file uploading, it will automatically draw data from flask.request.files if the form is posted. The data attribute of FileField will be an instance of Werkzeug FileStorage.

For example:

from werkzeug import secure_filename
from flask_wtf.file import FileField

class PhotoForm(Form):
    photo = FileField('Your photo')

@app.route('/upload/', methods=('GET', 'POST'))
def upload():
    form = PhotoForm()
    if form.validate_on_submit():
        filename = secure_filename(
        filename = None
    return render_template('upload.html', form=form, filename=filename)


Remember to set the enctype of your HTML form to multipart/form-data, which means:

<form action="/upload/" method="POST" enctype="multipart/form-data">

More than that, Flask-WTF supports validation on file uploading. There are FileRequired and FileAllowed.

The FileAllowed works well with Flask-Uploads, for example:

from flask.ext.uploads import UploadSet, IMAGES
from flask_wtf import Form
from flask_wtf.file import FileField, FileAllowed, FileRequired

images = UploadSet('images', IMAGES)

class UploadForm(Form):
    upload = FileField('image', validators=[
        FileAllowed(images, 'Images only!')

It can work without Flask-Uploads too. You need to pass the extensions to FileAllowed:

class UploadForm(Form):
    upload = FileField('image', validators=[
        FileAllowed(['jpg', 'png'], 'Images only!')

HTML5 Widgets


HTML5 widgets and fields are builtin of wtforms since 1.0.4. You should consider import them from wtforms if possible.

However, wtforms missed a DateInput, which is why we still keep the html5 module. Once wtforms has a full feature of html5 forms, Flask-WTF will drop supporting for them.

You can import a number of HTML5 widgets from flask_wtf.html5:

from flask_wtf.html5 import URLField
from wtforms.validators import url

class LinkForm(Form):
    url = URLField(validators=[url()])


Flask-WTF also provides Recaptcha support through a RecaptchaField:

from flask_wtf import Form, RecaptchaField
from wtforms import TextField

class SignupForm(Form):
    username = TextField('Username')
    recaptcha = RecaptchaField()

This comes together with a number of configuration, which you have to implement them.

RECAPTCHA_USE_SSL Enable/disable recaptcha through ssl. Default is False.
RECAPTCHA_PUBLIC_KEY required A public key.
RECAPTCHA_PRIVATE_KEY required A private key.
RECAPTCHA_OPTIONS optional A dict of configuration options.

For testing your application, if app.testing is True, recaptcha field will always be valid for you convenience.

And it can be easily setup in the templates:

<form action="/" method="post">
    {{ form.username }}
    {{ form.recaptcha }}

We have an example for you: recaptcha@github.

Table Of Contents

Related Topics

This Page