Flask provides an alternative to web forms by creating a form class in the application, implementing the fields in the template and handling the data back in the application.
A Flask form class inherits from the class FlaskForm
and includes attributes for every field:
class MyForm(FlaskForm): my_textfield = StringField("TextLabel") my_submit = SubmitField("SubmitName")
This simple class will enable the creation of a form with a text field and a submit button.
The class inherits from the class FlaskForm
which allows it to implement the form as template variables and then collect the data once submitted. FlaskForm
is a part of FlaskWTF.
Access to the fields of this form class is done through the attributes, my_textfield
and my_submit
. The StringField
and SubmitField
classes are the same as <input type=text...
and <input type=submit...
respectively and are part of the WTForms library.
Below is a simple Flask app with the form class.
from flask import Flask, render_template from flask_wtf import FlaskForm from wtforms import StringField, SubmitField app = Flask(__name__) app.config["SECRET_KEY"] = "my_secret" class MyForm(FlaskForm): my_textfield = StringField("TextLabel") my_submit = SubmitField("SubmitName") @app.route("/") def my_route(): flask_form = MyForm() return render_template("my_template", template_form=flask_form)
First note the new import statements. FlaskForm
is imported from the flask_wtf
module and both form fields import from wtforms
.
The next new line is:
app.config["SECRET_KEY"] = "my_secret"
This line is a way to protect against CSRF or Cross-Site Request Forgery. Without going into too much detail, CSRF is an attack that used to gain control of a web application.
Next is the MyForm
class definition. It inherits from FlaskForm
and has attributes for the text and submit fields. For each field the label is passed as the only argument.
Lastly, in order to use this form in our template, we must create an instance of it and pass it to the template using render_template()
. We will look at applying the form in the template in the next exercise.
Instructions
In app.py note the extra import statements and the setting of the "SECRET_KEY"
:
from flask_wtf import FlaskForm from wtforms import StringField, SubmitField
and
app.config["SECRET_KEY"] = "mysecret"
Other things to note moving forward:
- The
comments
dictionary is added to thehelper.py
import statement methods=["GET", "POST"]
has been added to the recipe route- The recipe route’s
render_template()
function call has a new keyword argumenttemplate_comments=comments[id]
- A comments unordered list has been added to the recipe.html template
Take a look at the changes and run the code to move on.
Above the index route in app.py, create a class called CommentForm
that inherits from FlaskForm
.
Add a class attribute named comment
and assign it a StringField
with label "Comment"
.
Create a submit field inside the class with the label "Add Comment"
and assign it to a variable called, submit
.
Lastly, in the recipe()
route you’ll see that render_template
has the argument template_form=comment_form
. Just above render_template()
create the variable comment_form
and assign it an instance of CommentForm
.