How to Create Form Using WTForms in Flask: Simple Guide
To create a form using
WTForms in Flask, define a form class inheriting from FlaskForm with fields like StringField and SubmitField. Then, render the form in a Flask route and template, and validate it on submission using form.validate_on_submit().Syntax
Creating a form with WTForms in Flask involves these parts:
- Form class: Inherit from
FlaskFormto define your form. - Fields: Use field types like
StringField,PasswordField, andSubmitFieldto add inputs. - Validators: Add rules like
DataRequired()to ensure input is valid. - Form handling: In your Flask route, create a form instance, check
form.validate_on_submit(), and process data.
python
from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired class MyForm(FlaskForm): name = StringField('Name', validators=[DataRequired()]) submit = SubmitField('Submit')
Example
This example shows a complete Flask app with a WTForms form that asks for a name and displays a greeting after submission.
python
from flask import Flask, render_template_string, request from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired app = Flask(__name__) app.config['SECRET_KEY'] = 'secret-key' class NameForm(FlaskForm): name = StringField('Enter your name', validators=[DataRequired()]) submit = SubmitField('Greet me') @app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() greeting = '' if form.validate_on_submit(): greeting = f'Hello, {form.name.data}!' return render_template_string(''' <form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name(size=20) }}<br><br> {{ form.submit() }} </form> <p>{{ greeting }}</p> ''', form=form, greeting=greeting) if __name__ == '__main__': app.run(debug=True)
Output
A web page with a text input labeled 'Enter your name' and a 'Greet me' button. After typing a name and submitting, the page shows 'Hello, [name]!' below the form.
Common Pitfalls
Common mistakes when using WTForms in Flask include:
- Not setting
SECRET_KEYin Flask config, which is required for CSRF protection. - Forgetting to include
{{ form.hidden_tag() }}in the template, which renders CSRF tokens. - Not using
validate_on_submit()to check form validity before processing data. - Using incorrect field names or missing validators causing validation to fail silently.
python
from flask import Flask, render_template_string from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired app = Flask(__name__) # Missing SECRET_KEY causes CSRF errors # app.config['SECRET_KEY'] = 'secret-key' class BadForm(FlaskForm): name = StringField('Name', validators=[DataRequired()]) submit = SubmitField('Submit') @app.route('/', methods=['GET', 'POST']) def bad_index(): form = BadForm() if form.validate_on_submit(): return f'Hello, {form.name.data}!' return render_template_string(''' <form method="POST"> <!-- Missing hidden_tag() causes CSRF token missing --> {{ form.name.label }} {{ form.name() }}<br> {{ form.submit() }} </form> ''', form=form) if __name__ == '__main__': app.run(debug=True)
Quick Reference
Key points for WTForms in Flask:
- Always set
app.config['SECRET_KEY']for security. - Define forms by subclassing
FlaskForm. - Use fields like
StringField,PasswordField, andSubmitField. - Add validators like
DataRequired()to enforce input rules. - In templates, include
{{ form.hidden_tag() }}for CSRF protection. - Check
form.validate_on_submit()before processing form data.
Key Takeaways
Define forms by subclassing FlaskForm and adding fields with validators.
Always set SECRET_KEY in Flask config to enable CSRF protection.
Include {{ form.hidden_tag() }} in templates to render CSRF tokens.
Use form.validate_on_submit() to check if form data is valid before processing.
Render forms in templates and handle submissions in Flask routes.