Skip to content

Form Validation

Validation ensures:

  • required fields are present
  • values match expected patterns (email)
  • lengths/ranges are safe

Common validators

WTForms ships many validators:

  • DataRequired()DataRequired() / InputRequired()InputRequired()
  • Email()Email()
  • Length(min=, max=)Length(min=, max=)
  • NumberRange(min=, max=)NumberRange(min=, max=)
  • Regexp()Regexp()

Example:

python
from wtforms.validators import DataRequired, Length
 
username = StringField("Username", validators=[DataRequired(), Length(min=3, max=20)])
python
from wtforms.validators import DataRequired, Length
 
username = StringField("Username", validators=[DataRequired(), Length(min=3, max=20)])

Validation errors

When validation fails, errors are stored per field:

  • form.username.errorsform.username.errors

You can show them in templates:

html
{% for error in form.username.errors %}
  <p class="error">{{ error }}</p>
{% endfor %}
html
{% for error in form.username.errors %}
  <p class="error">{{ error }}</p>
{% endfor %}

Custom validation

You can add custom validation methods:

python
class RegisterForm(FlaskForm):
    username = StringField("Username", validators=[DataRequired()])
 
    def validate_username(self, field):
        if " " in field.data:
            raise ValidationError("Username cannot contain spaces")
python
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

Here’s the Post/Redirect/Get pattern that keeps form submissions safe from accidental resubmission.

diagram Post/Redirect/Get pattern mermaid
Form validation flow with re-render on errors and redirect on success

🧪 Try It Yourself

Exercise 1 – Create a Flask App

Exercise 2 – Dynamic Route

Exercise 3 – Return JSON

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did