Day 45: Flask — Forms and Validation

Flask Forms Unleashed: Ensuring Data Integrity through Validation

Harshil Chovatiya
5 min readOct 12, 2024

Author: Harshil Chovatiya

Day 45: Flask — Forms and Validation | Harshil Chovatiya
Day 45: Flask — Forms and Validation | Harshil Chovatiya

Overview

Welcome to Day 45 of our Python and web development series! Today, we’ll explore an essential aspect of web development: handling forms and validating input in Flask. Forms are a fundamental component of web applications, allowing users to interact with your application by submitting data. Properly handling and validating this input is crucial for maintaining data integrity and security.

In this blog, we will cover:

  • Introduction to Flask-WTF
  • Creating Forms with Flask-WTF
  • Validating Form Data
  • Handling Form Submissions
  • Displaying Form Errors
  • Best Practices for Form Handling

Let’s dive into these topics to understand how to create robust forms and validate user input effectively in Flask.

Introduction to Flask-WTF

Flask-WTF is an extension for Flask that integrates WTForms with Flask. It simplifies form handling by providing a more Pythonic approach to form creation and validation. WTForms is a library that helps you define forms with field types, validation rules, and more.

Features of Flask-WTF:

  • Form Handling: Easily define and manage forms.
  • Validation: Built-in validators for common data validation needs.
  • CSRF Protection: Automatically adds CSRF tokens to forms for security.
  • Customizable: Allows for custom validation and error handling.

Installing Flask-WTF

To get started with Flask-WTF, you need to install it along with Flask:

pip install flask-wtf

Creating Forms with Flask-WTF

With Flask-WTF, you define forms as Python classes. Each class represents a form and its fields. Let’s create a simple contact form to illustrate this.

Setting Up the Project

  • Project Structure:
mkdir flask_forms
cd flask_forms
  • Set Up Virtual Environment and Install Dependencies:
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install Flask Flask-WTF
  • Create the Flask Application:

Create a file named app.py:

# app.py
from flask import Flask, render_template, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
class ContactForm(FlaskForm):
name = StringField('Name', validators=[DataRequired(), Length(min=2, max=50)])
email = StringField('Email', validators=[DataRequired()])
message = TextAreaField('Message', validators=[DataRequired(), Length(min=10, max=500)])
submit = SubmitField('Send')
@app.route('/contact', methods=['GET', 'POST'])
def contact():
form = ContactForm()
if form.validate_on_submit():
# Process the form data here
return redirect(url_for('success'))
return render_template('contact.html', form=form)
@app.route('/success')
def success():
return "Form submitted successfully!"
if __name__ == '__main__':
app.run(debug=True)
  • Create the templates Directory and contact.html Template:

Inside the flask_forms directory, create a folder named templates and add contact.html:

<!-- templates/contact.html -->
<!DOCTYPE html>
<html>
<head>
<title>Contact Us</title>
</head>
<body>
<h1>Contact Us</h1>
<form method="POST" action="{{ url_for('contact') }}">
{{ form.hidden_tag() }}
<p>
{{ form.name.label }}<br>
{{ form.name(size=32) }}<br>
{% for error in form.name.errors %}
<span style="color: red;">[{{ error }}]</span><br>
{% endfor %}
</p>
<p>
{{ form.email.label }}<br>
{{ form.email(size=32) }}<br>
{% for error in form.email.errors %}
<span style="color: red;">[{{ error }}]</span><br>
{% endfor %}
</p>
<p>
{{ form.message.label }}<br>
{{ form.message(rows=5, cols=40) }}<br>
{% for error in form.message.errors %}
<span style="color: red;">[{{ error }}]</span><br>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
</body>
</html>
Flask Form in python | Harshil Chovatiya
Flask Form in python | Harshil Chovatiya

Explanation:

  • ContactForm Class: Defines the form fields and validation rules.
  • form.validate_on_submit(): Validates the form data when submitted.
  • {{ form.hidden_tag() }}: Adds a CSRF token to the form.
  • {% for error in form.field.errors %}: Displays validation errors for each field.

Validating Form Data

Validation ensures that the data submitted through forms is correct and secure. Flask-WTF provides several built-in validators, but you can also create custom validators.

Built-in Validators

  • DataRequired(): Ensures that the field is not empty.
  • Length(min, max): Validates the length of the input.
  • Email(): Validates that the input is a valid email address.

Creating Custom Validators

Custom validators allow you to define complex validation logic. Here’s how to create and use a custom validator:

  1. Define a Custom Validator:
# app.py
from wtforms import ValidationError
def validate_email_domain(form, field):
if not field.data.endswith('@example.com'):
raise ValidationError('Email must be from the domain @example.com')
  1. Apply the Custom Validator to a Field:
# app.py
class ContactForm(FlaskForm):
# other fields
email = StringField('Email', validators=[DataRequired(), validate_email_domain])

Explanation:

  • validate_email_domain Function: Checks if the email ends with @example.com.
  • ValidationError: Raised if validation fails.

Handling Form Submissions

Handling form submissions involves processing the data and performing actions like saving to a database, sending emails, or redirecting users.

Example: Processing Form Data

Update the contact route in app.py to handle form submissions:

# app.py

from flask import Flask, render_template, redirect, url_for, flash
@app.route('/contact', methods=['GET', 'POST'])
def contact():
form = ContactForm()
if form.validate_on_submit():
name = form.name.data
email = form.email.data
message = form.message.data
# Here you can add code to process the form data (e.g., save to database, send email)
flash(f'Thank you {name}, your message has been sent!')
return redirect(url_for('success'))
return render_template('contact.html', form=form)

Explanation:

  • flash Function: Used to display a message to the user after form submission.
  • Processing Form Data: Handle the form data according to your application’s requirements.

Displaying Form Errors

Displaying form errors helps users correct their input. Flask-WTF makes it easy to show validation errors next to form fields.

Example: Displaying Errors in the Template

Update the contact.html template to show errors for each field:

<!-- templates/contact.html -->

<!-- Inside <form> tag -->
{% for field in form %}
<p>
{{ field.label }}<br>
{{ field(size=32) }}<br>
{% for error in field.errors %}
<span style="color: red;">[{{ error }}]</span><br>
{% endfor %}
</p>
{% endfor %}

Explanation:

  • {{ field.errors }}: Displays validation errors associated with each field.
Error handling or validation in flask forms | Harshil Chovatiya
Error handling or validation in flask forms | Harshil Chovatiya

Best Practices for Form Handling

  • Sanitize and Validate Input: Always validate and sanitize user input to prevent security vulnerabilities such as SQL injection or cross-site scripting (XSS).
  • Provide Clear Error Messages: Ensure that error messages are clear and helpful, guiding users to correct their input.
  • Use CSRF Protection: Flask-WTF automatically adds CSRF protection to forms, preventing cross-site request forgery attacks.
  • Handle Form Submission Gracefully: Provide feedback to users after form submission, whether successful or with errors.
  • Organize Forms: Keep your forms organized in separate files or modules if your application grows larger. This approach improves maintainability and readability.

Conclusion

On Day 45, we explored handling forms and validating input in Flask using Flask-WTF. We learned how to create and manage forms, apply built-in and custom validators, and handle form submissions effectively. Proper form handling and validation are crucial for building secure and user-friendly web applications.

By integrating these techniques into your Flask projects, you’ll ensure that user data is handled correctly and that your web applications provide a smooth and reliable user experience.

Thank you for following along with Day 45 of our Python and web development series.

Happy coding!

by Harshil Chovatiya

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Harshil Chovatiya
Harshil Chovatiya

Written by Harshil Chovatiya

Passionate Python and Flutter developer creating dynamic apps and tools. Focused on seamless user experiences and backend efficiency.

No responses yet

Write a response