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:
- Creating HTML Forms
- Handling Form Submissions in Flask
- Using Flask-WTF for Form Handling
- Practical Example: User Registration Form
- 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.
- 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. Themethods=['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.
- 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:
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.
- 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.
Flask Web Development Course
Module 1: Introduction to Flask
- What is Flask?
- Setting Up Your Development Environment
- Creating Your First Flask Application
- Understanding Flask Application Structure
Module 2: Basic Flask Concepts
- Routing and URL Mapping
- Handling HTTP Methods
- Rendering Templates with Jinja2
- Working with Static Files
Module 3: Forms and User Input
Module 4: Database Integration
- Introduction to Flask-SQLAlchemy
- Defining Models
- Performing CRUD Operations
- Database Migrations with Flask-Migrate
Module 5: User Authentication
Module 6: Advanced Flask Concepts
Module 7: RESTful APIs with Flask
Module 8: Deployment and Production
- Configuring Flask for Production
- Deploying to Heroku
- Deploying to AWS
- Monitoring and Performance Tuning