Forms
Handling forms in Flask involves capturing and processing data submitted by users through HTML forms. Flask provides several ways to work with form data, primarily using the request
object and the Flask-WTF
extension for more advanced form handling. Here's a detailed guide on how to handle forms in Flask:
Basic Form Handling with Flask
- Create the HTML Form: Define your form in an HTML template.
<!-- templates/form.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form Page</title> </head> <body> <h1>Submit Your Information</h1> <form action="/submit" method="post"> <label for="name">Name:</label> <input type="text" id="name" name="name" required><br> <label for="email">Email:</label> <input type="email" id="email" name="email" required><br> <button type="submit">Submit</button> </form> </body> </html>
- Define the Route to Display the Form:
# app/routes.py from flask import Blueprint, render_template, request, redirect, url_for bp = Blueprint('main', __name__) @bp.route('/form') def form(): return render_template('form.html')
- Define the Route to Handle Form Submission:
@bp.route('/submit', methods=['POST']) def submit(): name = request.form['name'] email = request.form['email'] # Process the form data (e.g., save to database) return f'Thank you, {name}! We have received your email: {email}'
Advanced Form Handling with Flask-WTF
For more complex forms and validation, using the Flask-WTF extension is recommended. Flask-WTF integrates Flask with WTForms, providing form rendering, validation, and CSRF protection.
- Install Flask-WTF:
pip install flask-wtf
- Create a Form Class: Define your form class using WTForms.
# app/forms.py from flask_wtf import FlaskForm from wtforms import StringField, EmailField, SubmitField from wtforms.validators import DataRequired, Email class ContactForm(FlaskForm): name = StringField('Name', validators=[DataRequired()]) email = EmailField('Email', validators=[DataRequired(), Email()]) submit = SubmitField('Submit')
- Update Configuration: Add a secret key for CSRF protection in
config.py
.class Config: SECRET_KEY = 'you-will-never-guess' # Or use os.environ.get('SECRET_KEY')
- Update the Route to Use the Form:
# app/routes.py from .forms import ContactForm @bp.route('/contact', methods=['GET', 'POST']) def contact(): form = ContactForm() if form.validate_on_submit(): name = form.name.data email = form.email.data # Process the form data (e.g., save to database) return f'Thank you, {name}! We have received your email: {email}' return render_template('contact.html', form=form)
- Update the HTML Template to Use WTForms:
<!-- templates/contact.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Contact Form</title> </head> <body> <h1>Contact Us</h1> <form method="post"> {{ form.hidden_tag() }} <p> {{ form.name.label }}<br> {{ form.name(size=20) }}<br> {% for error in form.name.errors %} <span style="color: red;">[{{ error }}]</span> {% endfor %} </p> <p> {{ form.email.label }}<br> {{ form.email(size=20) }}<br> {% for error in form.email.errors %} <span style="color: red;">[{{ error }}]</span> {% endfor %} </p> <p>{{ form.submit() }}</p> </form> </body> </html>
Example Project: Form Handling
Project Structure:
my_flask_project/
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── forms.py
│ ├── templates/
│ │ ├── form.html
│ │ └── contact.html
│ └── static/
├── run.py
└── config.py
app/forms.py:
from flask_wtf import FlaskForm
from wtforms import StringField, EmailField, SubmitField
from wtforms.validators import DataRequired, Email
class ContactForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
email = EmailField('Email', validators=[DataRequired(), Email()])
submit = SubmitField('Submit')
app/routes.py:
from flask import Blueprint, render_template, request, redirect, url_for
from .forms import ContactForm
bp = Blueprint('main', __name__)
@bp.route('/form')
def form():
return render_template('form.html')
@bp.route('/submit', methods=['POST'])
def submit():
name = request.form['name']
email = request.form['email']
return f'Thank you, {name}! We have received your email: {email}'
@bp.route('/contact', methods=['GET', 'POST'])
def contact():
form = ContactForm()
if form.validate_on_submit():
name = form.name.data
email = form.email.data
return f'Thank you, {name}! We have received your email: {email}'
return render_template('contact.html', form=form)
run.py:
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
config.py:
class Config:
SECRET_KEY = 'you-will-never-guess'
Summary
- Basic Form Handling: Use the
request
object to access form data directly from the template. - Advanced Form Handling: Use Flask-WTF for form validation, CSRF protection, and rendering forms with WTForms.
- CSRF Protection: Ensure your forms are secure with CSRF tokens, especially when using Flask-WTF.
By following these guidelines, you can effectively handle forms in your Flask applications, from simple data submissions to more complex interactions with validations and CSRF protection.