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 WTFormsVerified import paths — ran on the pinned version, not inferred.
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.
Migrate to the equivalent standalone library for any removed `wtforms.ext.*` functionality. For example, `wtforms.ext.sqlalchemy` becomes `wtforms_sqlalchemy`.
Update imports and usage from `Required` to `DataRequired`.
Replace all instances of `TextField` with `StringField`.
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.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.
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).
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`.
First, instantiate your form class (e.g., `form = MyForm(request.form)`) and then call the validation method on the instance (e.g., `form.validate()`).
Specify the `form_class` argument when defining `FormField` inside a `FieldList`, pointing it to your nested form class, e.g., `items = FieldList(FormField(MyNestedForm))`.
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')]`).