python 53 lines · 8 steps

Cleaning form input with Flask-WTF filters

Filter functions normalize each field's raw input before validators ever see it, so validation runs against clean data.

Explained by highlit
1import re
2 
3from flask_wtf import FlaskForm
4from wtforms import StringField, TextAreaField, PasswordField
5from wtforms.validators import DataRequired, Email, Length
6 
7_WHITESPACE_RUN = re.compile(r"\s+")
8 
9 
10def strip_whitespace(value):
11 if value is None:
12 return value
13 return value.strip()
14 
15 
16def collapse_whitespace(value):
17 if value is None:
18 return value
19 return _WHITESPACE_RUN.sub(" ", value).strip()
20 
21 
22def empty_to_none(value):
23 if value is None:
24 return value
25 stripped = value.strip()
26 return stripped or None
27 
28 
29class ProfileForm(FlaskForm):
30 full_name = StringField(
31 "Full name",
32 filters=[collapse_whitespace],
33 validators=[DataRequired(), Length(max=120)],
34 )
35 email = StringField(
36 "Email",
37 filters=[strip_whitespace, lambda v: v.lower() if v else v],
38 validators=[DataRequired(), Email()],
39 )
40 company = StringField(
41 "Company",
42 filters=[empty_to_none],
43 validators=[Length(max=120)],
44 )
45 bio = TextAreaField(
46 "Bio",
47 filters=[strip_whitespace],
48 validators=[Length(max=2000)],
49 )
50 password = PasswordField(
51 "Password",
52 validators=[DataRequired(), Length(min=8)],
53 )
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Filters transform submitted values before validators run, so validation checks the cleaned data.
  2. 2Guarding each filter against None keeps normalization safe for fields that were never filled in.
  3. 3Small composable filter functions let you mix and match normalization per field without duplicating logic.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Cleaning form input with Flask-WTF filters — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code