Registry / web-framework / wtforms

wtforms

JSON →
library3.2.2pypypi✓ verified 25d ago

WTForms is a flexible forms validation and rendering library for Python web development, providing tools for data validation, CSRF protection, and internationalization. It is designed to be framework-agnostic, working with various web frameworks and template engines. It is actively maintained with regular releases.

pip install WTForms
INSTALL
IMPORT
SIG · WTFORMS
W
wtforms
web-frameworkpythonv3.2.2
Install
1.7s avg
Import
73ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.2.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.074s · 18.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.072s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Form
from wtforms import Form
StringField
from wtforms import StringField
from wtforms import TextField
TextField was an alias for StringField, deprecated in WTForms 2.x and removed in 3.x. Use StringField instead.
SubmitField
from wtforms import SubmitField
validators
from wtforms import validators
DataRequired
from wtforms.validators import DataRequired
from wtforms.validators import Required
Required was renamed to DataRequired in WTForms 2.x.

Defines a simple login form with username, password, and submit fields, including basic length and data required validators. It then demonstrates instantiating the form with mock data and performing validation. For web frameworks, you would typically pass `request.form` or `request.json` to the form constructor.

from wtforms import Form, StringField, PasswordField, validators, SubmitField class LoginForm(Form): username = StringField('Username', [validators.Length(min=4, max=25), validators.DataRequired()]) password = PasswordField('Password', [validators.DataRequired(), validators.Length(min=8)]) submit = SubmitField('Sign In') # Example usage (simulating a request) if __name__ == '__main__': # Simulate form data from a POST request mock_form_data = { 'username': 'testuser', 'password': 'securepassword', 'submit': 'Sign In' } form = LoginForm(data=mock_form_data) if form.validate(): print(f"Form validated successfully for user: {form.username.data}") # In a real application, you'd process the data here else: print("Form validation failed:") for field, errors in form.errors.items(): for error in errors: print(f" {field}: {error}") # Example with invalid data invalid_form_data = { 'username': 'abc', 'password': 'short', 'submit': 'Sign In' } invalid_form = LoginForm(data=invalid_form_data) if not invalid_form.validate(): print("\nInvalid form submitted:") for field, errors in invalid_form.errors.items(): for error in errors: print(f" {field}: {error}")
Debug
Known issues
breakingThe `wtforms.ext.*` modules were completely removed in WTForms 3.0. These extensions (e.g., `wtforms.ext.sqlalchemy`, `wtforms.ext.appengine`, `wtforms.ext.csrf`) are now maintained as separate, independent packages (e.g., `WTForms-SQLAlchemy`, `WTForms-Appengine`, `Flask-WTF` for Flask integration with CSRF built-in).
fix
Migrate to the equivalent standalone library for any removed `wtforms.ext.*` functionality. For example, `wtforms.ext.sqlalchemy` becomes `wtforms_sqlalchemy`.
affects: 3.0.0 and later
breakingThe `wtforms.validators.Required` validator was renamed to `wtforms.validators.DataRequired` in WTForms 2.0 to clarify its behavior (checks for non-empty data).
fix
Update imports and usage from `Required` to `DataRequired`.
affects: 2.0.0 and later
breakingThe `TextField` alias for `StringField` was deprecated in WTForms 2.x and removed in 3.x.
fix
Replace all instances of `TextField` with `StringField`.
affects: 3.0.0 and later
breakingIn WTForms 3.2.0, the key used for form-level errors (not specific to a field) moved from `None` to an empty string `""`.
fix
When accessing form errors, check `form.errors.get('')` instead of `form.errors.get(None)`. If you need to revert to the old behavior, you can set `_form_error_key=None` on your form class.
affects: 3.2.0 and later
gotchaWTForms provides the `FileField` for file input but does not handle the actual file upload storage or processing. This is typically managed by the underlying web framework (e.g., Flask's `request.files`, Django's `request.FILES`).
fix
Implement file handling logic separately in your application's view functions, utilizing your web framework's capabilities for processing uploaded files after WTForms validates the field's presence/metadata.
affects: All versions
gotchaWTForms handles CSRF protection directly within the core library since version 2.0, moving it out of `wtforms.ext.csrf`. If integrating with frameworks like Flask, companion libraries such as `Flask-WTF` often provide a more streamlined, automated CSRF implementation.
fix
For basic usage, ensure your form includes a `CSRFTokenField` and your template renders it. If using a framework-specific integration, consult its documentation (e.g., `Flask-WTF` automatically handles this if `SECRET_KEY` is set).
affects: 2.0.0 and later
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'wtforms.ext'
The `wtforms.ext` module, which contained various extensions, was removed in WTForms 3.0. Its functionality either moved into the core library, was deprecated, or spun off into separate, dedicated packages (like `wtforms_sqlalchemy`).
fix
Identify the specific class or function you were importing from `wtforms.ext` and update the import path. For example, `QuerySelectField` moved to `wtforms_sqlalchemy` and needs `from wtforms_sqlalchemy.fields import QuerySelectField`.
AttributeError: 'Form' object has no attribute 'validate'
This error occurs when attempting to call a validation method (like `validate()` or `validate_on_submit()`) on a form *class* itself rather than an *instance* of the form.
fix
First, instantiate your form class (e.g., `form = MyForm(request.form)`) and then call the validation method on the instance (e.g., `form.validate()`).
TypeError: __init__() missing 1 required positional argument: 'form_class'
When using `FormField` within a `FieldList`, the `FormField` constructor requires the `form_class` argument to be explicitly provided, indicating which nested form should be used.
fix
Specify the `form_class` argument when defining `FormField` inside a `FieldList`, pointing it to your nested form class, e.g., `items = FieldList(FormField(MyNestedForm))`.
ValueError: ('field_name', ['Not a valid choice'])
This error (or similar for other choice fields) occurs when the submitted value for a `SelectField`, `RadioField`, or `SelectMultipleField` does not match any of the `value` components in the `choices` provided to the field.
fix
Ensure that the `choices` iterable for the field contains all possible valid options, and that the submitted data's value exactly matches one of the `value` parts in your `(value, label)` tuples (e.g., `[(1, 'Option 1'), (2, 'Option 2')]`).
Upgrade
Version history
3.2.2latest on PyPI · released May 3, 2026
Audit
Dependencies
pythonrequiredWTForms requires Python 3.9 or newer.
Agent activity
35 hits · last 30 days
node
28
OpenAI (training)
1
Resources
wtforms — pip install wtforms · libregistry