In this section, we will explore how to create and handle forms in Flask. Forms are a fundamental part of web applications, allowing users to submit data that can be processed by the server. We will cover the following topics:

  1. Creating HTML Forms
  2. Handling Form Submissions in Flask
  3. Using Flask-WTF for Form Handling
  4. Practical Example: User Registration Form

  1. Creating HTML Forms

HTML forms are used to collect user input. Here is a basic example of an HTML form:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Simple Form</title>
</head>
<body>
    <form action="/submit" method="post">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name">
        <br>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email">
        <br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

Explanation:

  • <form action="/submit" method="post">: Specifies the URL to which the form data will be sent and the HTTP method to use.
  • <label for="name">Name:</label>: A label for the input field.
  • <input type="text" id="name" name="name">: A text input field for the user's name.
  • <input type="email" id="email" name="email">: An email input field for the user's email.
  • <input type="submit" value="Submit">: A submit button to send the form data.

  1. Handling Form Submissions in Flask

To handle form submissions in Flask, we need to create a route that will process the form data. Here is an example:

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('form.html')

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form['name']
    email = request.form['email']
    return f"Name: {name}, Email: {email}"

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • @app.route('/'): Defines the route for the home page, which renders the form.
  • @app.route('/submit', methods=['POST']): Defines the route to handle form submissions. The methods=['POST'] argument specifies that this route only accepts POST requests.
  • request.form['name']: Retrieves the value of the 'name' input field from the form.
  • request.form['email']: Retrieves the value of the 'email' input field from the form.

  1. Using Flask-WTF for Form Handling

Flask-WTF is an extension that simplifies form handling in Flask by integrating with WTForms. To use Flask-WTF, you need to install it first:

pip install flask-wtf

Creating a Form with Flask-WTF

Here is an example of how to create and handle a form using Flask-WTF:

from flask import Flask, render_template, request, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'

class MyForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired()])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = MyForm()
    if form.validate_on_submit():
        name = form.name.data
        email = form.email.data
        return f"Name: {name}, Email: {email}"
    return render_template('form_wtf.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • FlaskForm: A base class for creating forms in Flask-WTF.
  • StringField: A field for text input.
  • SubmitField: A field for the submit button.
  • validators=[DataRequired()]: Ensures that the field is not empty.
  • form.validate_on_submit(): Checks if the form is submitted and valid.

HTML Template (form_wtf.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form with Flask-WTF</title>
</head>
<body>
    <form method="POST">
        {{ 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>
            {% endfor %}
        </p>
        <p>
            {{ form.email.label }}<br>
            {{ form.email(size=32) }}<br>
            {% for error in form.email.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
</body>
</html>

Explanation:

  • {{ form.hidden_tag() }}: Generates a hidden tag for CSRF protection.
  • {{ form.name.label }}: Renders the label for the 'name' field.
  • {{ form.name(size=32) }}: Renders the 'name' input field with a size attribute.
  • {% for error in form.name.errors %}: Iterates over any validation errors for the 'name' field and displays them.

  1. Practical Example: User Registration Form

Let's create a more practical example: a user registration form.

Flask Code

from flask import Flask, render_template, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Register')

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        username = form.username.data
        email = form.email.data
        # Here you would typically save the user to the database
        return f"User {username} registered with email {email}"
    return render_template('register.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

HTML Template (register.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>
    <h1>Register</h1>
    <form method="POST">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.email.label }}<br>
            {{ form.email(size=32) }}<br>
            {% for error in form.email.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.confirm_password.label }}<br>
            {{ form.confirm_password(size=32) }}<br>
            {% for error in form.confirm_password.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
</body>
</html>

Explanation:

  • PasswordField: A field for password input.
  • EqualTo('password'): Ensures that the 'confirm_password' field matches the 'password' field.
  • The form template includes error handling for each field.

Summary

In this section, we covered:

  • How to create basic HTML forms.
  • How to handle form submissions in Flask.
  • How to use Flask-WTF to simplify form handling and validation.
  • A practical example of a user registration form.

By understanding these concepts, you can create and handle forms in your Flask applications effectively. In the next section, we will dive into form validation with WTForms to ensure that user input meets the required criteria.

© Copyright 2024. All rights reserved