Open In App

Flask-WTF Explained & How to Use it

Last Updated : 17 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Flask-WTF is a Flask extension that integrates the WTForms library, which provides useful features for creating and handling forms in a simple way for a Flask web application. WTForms is a Python library for working with forms and form fields. It provides a flexible framework for creating forms, handling validation, and rendering forms in HTML. In this article, let us understand how the Flask-WTF library handles web forms with a Signup form example. Before handling forms, let us know the features, field types, and prerequisites needed to develop the Signup form application.
Some of the key features of Flask-WTF include:

Secure handling of forms: Flask-WTF automatically handles cross-site request forgery (CSRF) protection, which is a security measure to prevent unauthorized form submissions.

Form rendering: Flask-WTF provides a simple way to render forms in HTML templates. It also supports various form field types, such as text fields, checkboxes, and select fields.

Validation: Flask-WTF provides built-in validation for form fields, such as required fields, length constraints, and pattern matching. It also supports custom validation methods.

File uploads: Flask-WTF can handle file uploads, which allows users to upload files through a form.

Prerequisites to develop the flask application:

Basic knowledge of Python: Flask is written in Python, so having a basic understanding of Python programming is essential.

Familiarity with HTML, CSS, and JavaScript: Flask applications typically use HTML, CSS, and JavaScript to render the user interface, so having a basic understanding of these technologies is helpful.

Knowledge of the Flask framework: Flask is a microweb framework for Python, so having a basic understanding of how Flask works, including its routing, templates, and request/response cycles, is necessary.

To use Flask-WTF in the application, we first need to install it using pip and then import it into the application. We then create forms using the WTForms library and use Flask-WTF functions to handle form submissions and validation.
So, lets install flask-WTF by pip:

pip install flask-WTF

In Flask-WTF, forms are defined as classes that extend the ‘FlaskForm’ class. The fields in a form are defined as class variables in the form class. So now let’s understand the field types of flask-WTForms.

WTForms provides several built-in field types, some of which are:

  1. StringField: Represents a text input field, used for entering strings. Basically, this field supports string-type data.
  2. PasswordField: Represents a password input field, used for entering password values.
  3. BooleanField: Represents a checkbox input field, used for selecting boolean values such as True or False.
  4. DecimalField: Represents a text input field, used for decimals.
  5. RadioField: Represents a group of radio buttons, used for selecting a single value from a list of options.
  6. SelectField: Represents a select list, used for selecting a single value from a list of options.
  7. TextAreaField: Represents a textarea input field, used for entering multi-line text.
  8. FileField: Represents a file upload field, used for uploading files.

Flask-WTF Examples

Example 1:

Building a sample form using the above field types

Python3




# Importing Libraries..
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField
from wtforms import DecimalField, RadioField, SelectField, TextAreaField, FileField
from wtforms.validators import InputRequired
from werkzeug.security import generate_password_hash
  
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'
  
  
class MyForm(FlaskForm):
    name = StringField('Name', validators=[InputRequired()])
    password = PasswordField('Password', validators=[InputRequired()])
    remember_me = BooleanField('Remember me')
    salary = DecimalField('Salary', validators=[InputRequired()])
    gender = RadioField('Gender', choices=[
                        ('male', 'Male'), ('female', 'Female')])
    country = SelectField('Country', choices=[('IN', 'India'), ('US', 'United States'),
                                              ('UK', 'United Kingdom')])
    message = TextAreaField('Message', validators=[InputRequired()])
    photo = FileField('Photo')
  
  
@app.route('/', methods=['GET', 'POST'])
def index():
    form = MyForm()
    if form.validate_on_submit():
        name = form.name.data
        password = form.password.data
        remember_me = form.remember_me.data
        salary = form.salary.data
        gender = form.gender.data
        country = form.country.data
        message = form.message.data
        photo = form.photo.data.filename
        return f'Name: {name} < br > Password: {generate_password_hash(password)}
        <br > Remember me: {remember_me} < br > Salary: {salary} < br > Gender: {gender}
        <br > Country: {country} < br > Message: {message} < br > Photo: {photo}'
    return render_template('index.html', form=form)
  
  
if __name__ == '__main__':
    app.run()


HTML




<!DOCTYPE html>
<html>
<head>
    <title>My Form</title>
</head>
<body>
    <h1>My Form</h1>
    <form method="post" action="/" enctype="multipart/form-data">
        {{ form.csrf_token }}
        <p>{{ form.name.label }} {{ form.name() }}</p>
        <p>{{ form.password.label }} {{ form.password() }}</p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.salary.label }} {{ form.salary() }}</p>
        <p>{{ form.gender.label }} {{ form.gender() }}</p>
        <p>{{ form.country.label }} {{ form.country() }}</p>
        <p>{{ form.message.label }} {{ form.message() }}</p>
        <p>{{ form.photo.label }} {{ form.photo() }}</p>
        <p><input type="submit" value="Submit"></p>
    </form>
</body>
</html>


Simplifying the above Code –

In this example, we defined a MyForm class that inherits from FlaskForm and contains various fields that we want to use in our application. The StringField, PasswordField, BooleanField, DecimalField, RadioField, SelectField, TextAreaField, and FileField fields are defined with the appropriate validators and options.

In the index function, we created an instance of MyForm and passed it to the index.html template file. When the form is submitted, we validate it using the validate_on_submit method, and if it passes validation, we retrieve the data from the form fields and display it in the browser. In order to encrypt the password, we also used the generate_password_hash function and improved our form security.

Output:

Form details

Details of the submitted form

Output Video:

Example 2:

 Building a Sign-up form application using Flask-Sign-up

Now let’s see another example of a simple Sign-up form using the Flask-WTF library where we use the field types mentioned above in our application.

Python3




from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField ,SubmitField
from wtforms.validators import InputRequired, Length
  
app = Flask(__name__)
  
app.config['SECRET_KEY'] = 'secret'
  
# Using StringField, PasswordField andSubmitField from Flask-WTForms library 
# for username,password fields and submit button..  
class LoginForm(FlaskForm):
    username = StringField('Username', validators=[InputRequired('Username required!'), 
               Length(min=5, max=25, message='Username must be in 5 to 25 characters')])
    password = PasswordField('Password',validators=[InputRequired('Password required')])
    submit = SubmitField('Submit')
      
@app.route('/Signup', methods=['GET', 'POST'])
def form():
    form = LoginForm()
    if form.validate_on_submit():
        return '<h1>Hi {}!!. Your form is submitted successfully!!'.format
                 (form.username.data)
    return render_template('Signup.html', form=form)
  
if __name__ == '__main__':
    app.run(debug=True)


HTML




<!DOCTYPE html>
<html>
<head>
<title>Flask Form</title>
</head>
<body>
<h1>Signup </h1>
<form method="POST" action="{{ url_for('form') }}">
    {{ form.csrf_token }}
    {{ form.username.label }}
    {{ form.username }}
    <br>
    <br>
    {{ form.password.label }}
    {{ form.password }}
    <br>
    <br>
    {{ form.submit }}
</form>
</body>
</html>


Simplifying the above Code –

  1. First install Flask-WTF using pip: pip install flask-wtf.
  2. Import libraries: After successful installation import required libraries needed such as FlaskForm, StringField, and PasswordField for building the application.
  3. Create a form: Create a Python class (LoginForm) that extends FlaskForm and defines the fields for your form. Here, we defined 2 fields required for the Signup form which are Username and Password and a submit button to submit the form.
  4. When the form is submitted, Flask-WTF will automatically validate the form data and call the ‘validate’ methods defined in the form class. If the form data is valid, then we can handle the data submitted as needed.
  5. Render the form: Next, we used the render_template function in python script to render the form from through our HTML template (Signup.html). 
  6. <form method=”POST” action=”{{ url_for(‘form’) }}”> creates an HTML form that will submit the form data to the Flask route named ‘form’ using the HTTP POST method. The url_for function is used to generate the URL for the ‘form’ route based on its name.

{{ form.csrf_token }} adds a hidden input field to the form that contains a CSRF token. This is a security feature that helps prevent cross-site request forgery attacks.

{{ form.username.label }} renders an HTML label for the username field of the form.

{{ form.username }} renders an HTML input element for the username field of the form.

{{ form.password.label }} renders an HTML label for the password field of the form.

{{ form.password }} renders an HTML input element for the password field of the form.

{{ form. submit }} renders an HTML input element for the form’s submit button.
 

    6. Form submission: In our Flask route, we used the request.method attribute to determine if the form had been submitted. We can validate the form and handle the form submission only when it is submitted. In our application, we are returning a message to the user by displaying the form has been submitted successfully along with the username. 

Output:

Signup form 

Details of the Signup form

Form submitted

Output Video:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads