This video is available to students only

Building HTML Forms and Validating Data in a Flask App

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To 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.

Handling Forms

Forms are often the main way end users will interact with our web application, so it's important to make usable through the use of styling and error messages. A lot of the complexity implementing forms comes from data validations, adding CSRF protection, and the tediousness of writing HTML for each for field. In this chapter, we will be adding more forms to Yumroad and using a library called WTForms to make the implementation easier.

Writing HTML Forms

At this point we have already seen everything we need to render a form and process the input, so we will start with a plain HTML implementation and then switch to use a library that makes it easier.

To start with, we will create a template with a form with two fields that sends a POST request to the current URL.

yumroad-app/yumroad/templates/products/new_plain_form.html
{% extends "base_layout.html" %}

{% block title %} New Product {% endblock %}

{% block content %}
  <div class="container">
    <form method="POST">
      <label for="name">Name</label>
      <input type="text" class="form-control" name="name" />

      <label for="description">Description</label>
      <input type="textarea" class="form-control" name="description" />

      <br />
      <input type="submit" class="btn btn-primary"/>
    </form>
  </div>
{% endblock %}

To render the form, we will create a route that will handle GET requests to render the form.

@products.route('/create')
def create():
    return render_template('products/create.html')

To make the same route also handle the POST requests that will be sent when the form is submitted, we need to tell Flask that this route supports POST requests. To indicate that this route can support POST requests, we can specify the methods argument of the @products.route decorator and specify it to be a list of the two supported HTTP request methods (GET and POST).

To extract information about the current HTTP request, Flask provides a request object that you can import that will provide the details of the current HTTP request that Flask is handling (including form values and HTTP metadata).

If the request is a POST request (which we can check from request.method), we want to extract the data from the form (available in request.form) and create a new product. Once we have created the record, we can then redirect users using the redirect function from Flask to send them to the associated product page for the record that was just created. If the request is a GET, we can render the form like before.

from flask import render_template, redirect, request, ...

@products.route('/create', methods=['GET', 'POST'])
def create():
    # Using plain old request handling
    if request.method == 'POST':
        product = Product(name=request.form['name'], description=request.form['description'])
        db.session.add(product)
        db.session.commit()
        return redirect(url_for('product.details', product_id=product.id))
    return render_template('products/create.html')

At this point, we can submit the form and create new records for products that have a name of at least three characters. As soon as we submit an invalid input, like a product with no input whatsoever, we get a ValueError exception.

Value Error
Value Error

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.

Unlock This Course

Get unlimited access to Fullstack Flask: Build a Complete SaaS App with Flask with a single-time purchase.

Thumbnail for the \newline course Fullstack Flask: Build a Complete SaaS App with Flask