Form Validation
Validation ensures:
- required fields are present
- values match expected patterns (email)
- lengths/ranges are safe
Common validators
Section titled “Common validators”WTForms ships many validators:
DataRequired()/InputRequired()Email()Length(min=, max=)NumberRange(min=, max=)Regexp()
Example:
from wtforms.validators import DataRequired, Length
username = StringField("Username", validators=[DataRequired(), Length(min=3, max=20)])Validation errors
Section titled “Validation errors”When validation fails, errors are stored per field:
form.username.errors
You can show them in templates:
{% for error in form.username.errors %}
<p class="error">{{ error }}</p>
{% endfor %}Custom validation
Section titled “Custom validation”You can add custom validation methods:
class RegisterForm(FlaskForm):
username = StringField("Username", validators=[DataRequired()])
def validate_username(self, field):
if " " in field.data:
raise ValidationError("Username cannot contain spaces")Custom validators are great for business rules.
Visualize it
Section titled “Visualize it”Here’s the Post/Redirect/Get pattern that keeps form submissions safe from accidental resubmission.
flowchart TD
G["GET shows the form"] --> S["User submits (POST)"]
S --> V{"Validate"}
V -->|invalid| RE["Re-render form with errors"]
V -->|valid| SV["Save data"]
SV --> RD["Redirect (GET) to success page"]
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Create a Flask App
Section titled “Exercise 1 – Create a Flask App”Exercise 2 – Dynamic Route
Section titled “Exercise 2 – Dynamic Route”Exercise 3 – Return JSON
Section titled “Exercise 3 – Return JSON”pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading