Build HTML Forms in a Flask App With Python and WTForms
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Using WTForms
As we've seen, manually writing out logic for rendering the form and validations manually for each form in a complex SaaS application would quickly become tedious. WTForms is a Python library that helps us handle rendering form inputs, validation, editing data, and CSRF protection.
In the last chapter we used SQLAlchemy to provide us with a more "Python-ic" way to manage our database schema and querying. WTForms similarly provides a "Python-ic" abstraction for forms and form fields.
We're going to go back and convert our "New Product" form to use WTForms
.
To start with WTForms, add the Flask extension for WTForms Flask-WTF
your requirements.txt
file and then install it within your virtual environment. This will also install the actual WTForms
library as well.
(env) $ pip install -r requirements.txt
Then create a file in the yumroad
folder for us to store our form definitions called forms.py
. This file will be similar to models.py
in that it's a collection of classes where we declare the fields we want in our forms or models. You might see this pattern referred to as declarative class definitions.
If you see an error message about needing a secret key, you may need to add
WTF_CSRF_ENABLED = False
to yourBaseConfig
inyumroad/config.py
depending on which version of Flask you install. We will enable CSRF later on in this chapter
Creating a product with a form
Our product catalog needs a way for our users to create products, and the two fields we have right now are one for the name and description, so our form should also contain those two fields.
Our first step to creating a form will be to create a class to define the form. In our models file, the classes inherit from a base model from SQLAlchemy (db.Model
). Our form classes will similarly inherit from a base class named FlaskForm
provided by flask_wtf
.
from flask_wtf import FlaskForm
class ProductForm(FlaskForm):
# our fields will be declared here
pass
The next step is to declare the fields that this form will use. WTForms defines a set of fields for us to use, here are some of the common fields. A full list is available on the WTForms documentation.
Name | Type | Rendered As |
---|---|---|
StringField | String | text input |
TextAreaField | String | textarea input |
DateField | datetime.datetime | A text input for a formatted date string |
BooleanField | Boolean | A checkbox input |
SelectField | String | A select input |
FileField | Data | A file upload field |
We know that both of the fields we'll want our users to input are strings, but since the product description will be longer than the name, we want to render a textarea
input for the description and a text
input for the name.
To declare a field, we will import the field from wtforms.field
and then initialize them with the name of the field that we'd like to display to users.
from flask_wtf import FlaskForm
from wtforms.fields import StringField, SubmitField
class ProductForm(FlaskForm):
name = StringField('Name')
description = StringField('Description')
submit = SubmitField('Create Product')
This lesson preview is part of the Fullstack Flask: Build a Complete SaaS App with Flask course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Fullstack Flask: Build a Complete SaaS App with Flask with a single-time purchase.