Form Cheatsheet#

General Features:#

Refer to the official WTForms documentation.

Configuration Variables:#

app.py#
from quart import Quart

# Some configuration variables below are shown
# as non-default values for example purposes.
# Also, not all configuration variables are shown.
WTF_CSRF_ENABLED = True
WTF_CSRF_CHECK_DEFAULT = False
WTF_CSRF_SECRET_KEY = 'CSRFProtectsTheApp'
WTF_I18N_ENABLED = False

app = Quart(__name__)
app.config.from_pyfile(__name__)

# Setup the rest of the app & create forms.

Creating Forms:#

from quart-wtf import QuartForm
from wtforms import TextField, PasswordField
from wtforms.validators import DataRequired, Email, EqualTo
from wtforms.widgets import PasswordInput

class CreateAccountForm(StarletteForm):
    email = TextField(
        'Email address',
        validators=[
            DataRequired('Please enter your email address'),
            Email()
        ]
    )

    password = PasswordField(
        'Password',
        widget=PasswordInput(hide_value=False),
        validators=[
            DataRequired('Please enter your password'),
            EqualTo('password_confirm', message='Passwords must match')
        ]
    )

    password_confirm = PasswordField(
        'Confirm Password',
        widget=PasswordInput(hide_value=False),
        validators=[
            DataRequired('Please confirm your password')
        ]
    )

Calling in Routes:#

@app.route('/create-account', methods=['GET', 'POST'])
async def create_account():
    """GET|POST /create-account: Create account form handler
    """
    form = await CreateAccountForm.create_form()

    if await form.validate_on_submit():
        # Do what you need to do with the data.
        pass

    return await render_template('creataccount.html', form=form)

File Uploads:#

from quart_wtf import QuartForm, FileField, FileRequired
from werkzeug.utils import secure_filename

class PhotoForm(QuartForm):
    photo = FileField(validators=[FileRequired()])

@app.route('/upload', methods=['GET', 'POST'])
async async def upload():
    form = await PhotoForm().create_form()

    if await form.validate_on_submit():
        f = form.photo.data
        filename = secure_filename(f.filename)
        f.save(os.path.join(
            app.instance_path, 'photos', filename
        ))
        return redirect(url_for('index'))

    return await render_template('upload.html', form=form)

Form Validation:#

@app.route('/create-account', methods=['GET', 'POST'])
async def create_account():
    """GET|POST /create-account: Create account form handler
    """
    # initialize form
    form = await CreateAccountForm.create_form()

    # validate form
    if await form.validate_on_submit():
        # TODO: Save account credentials before returning redirect response
        return redirect(url_for('index'))

    return await render_template('creataccount.html', form=form)

Form Async Custom Validators:#

from quart_wtf import QuartForm
from wtforms import TextField, PasswordField, ValidationError
from wtforms.validators import DataRequired, Email, EqualTo


class CreateAccountForm(QuartForm):
    email = TextField(
        'Email address',
        validators=[
            DataRequired('Please enter your email address'),
            Email()
        ]
    )

    password = PasswordField(
        'Password',
        widget=PasswordInput(hide_value=False),
        validators=[
            DataRequired('Please enter your password'),
            EqualTo('password_confirm', message='Passwords must match')
        ]
    )

    password_confirm = PasswordField(
        'Confirm Password',
        widget=PasswordInput(hide_value=False),
        validators=[
            DataRequired('Please confirm your password')
        ]
    )

    async def async_validate_email(self, field):
        """Asynchronous validator to check if email is already in-use
        """
        # replace this with your own code
        if await make_database_request_here():
            raise ValidationError('Email is already in use')

File Uploading Validation:#

FileAllowed works well with Quart-Uploads:

from quart_uploads import UploadSet, IMAGES
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired

images = UploadSet('images', IMAGES)

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

It can also be used without Quart-Uploads by passing the extensions directly:

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