### Install WTForms using pip Source: https://github.com/pallets-eco/wtforms/blob/main/README.rst Use this command to install or update WTForms to the latest version. ```text pip install -U WTForms ``` -------------------------------- ### Full View Function Example Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md This is a complete example of a view function demonstrating the WTForms integration pattern, including object retrieval, form instantiation, validation, data population, saving, and rendering. ```python def edit_article(request): article = Article.get(...) form = MyForm(request.POST, article) if request.POST and form.validate(): form.populate_obj(article) article.save() return redirect('/articles') return render('edit.html', form=form, article=article) ``` -------------------------------- ### Install WTForms using pip Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Install the WTForms library using pip. This is the standard method for adding WTForms to your Python project. ```default pip install WTForms ``` -------------------------------- ### Field Definition Example Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Demonstrates how to define fields declaratively as members of a form class. ```APIDOC ## Field Definition Example Fields are defined as members on a form in a declarative fashion: ```python class MyForm(Form): name = StringField('Full Name', [validators.required(), validators.length(max=10)]) address = TextAreaField('Mailing Address', [validators.optional(), validators.length(max=200)]) ``` When a field is defined on a form, the construction parameters are saved until the form is instantiated. At form instantiation time, a copy of the field is made with all the parameters specified in the definition. Each instance of the field keeps its own field data and errors list. The label and validators can be passed to the constructor as sequential arguments, while all other arguments should be passed as keyword arguments. Some fields (such as [`SelectField`](#wtforms.fields.SelectField)) can also take additional field-specific keyword arguments. Consult the built-in fields reference for information on those. ``` -------------------------------- ### Basic SessionCSRF Setup in WTForms Source: https://github.com/pallets-eco/wtforms/blob/main/docs/csrf.md Configure a base form to use SessionCSRF with a secret and time limit. The CSRF context is explicitly passed during form instantiation. ```python from wtforms.csrf.session import SessionCSRF from datetime import timedelta class MyBaseForm(Form): class Meta: csrf = True csrf_class = SessionCSRF csrf_secret = b'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym' csrf_time_limit = timedelta(minutes=20) class Registration(MyBaseForm): name = StringField() def view(request): form = Registration(request.POST, meta={'csrf_context': request.session}) # rest of view here ``` -------------------------------- ### Jinja2 Template for Rendering Form Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Example of rendering a WTForms form within a Jinja2 template. It shows how to render labels and input fields, including passing HTML attributes. ```html+jinja
{{ form.username.label }}: {{ form.username(class="css_class") }}
{{ form.password.label }}: {{ form.password() }}
``` -------------------------------- ### Using a WTForms Form in a Django-like View Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Example of how to instantiate and validate a WTForms form within a web framework view, handling POST requests and saving validated data. ```default def register(request): form = RegistrationForm(request.POST) if request.method == 'POST' and form.validate(): user = User() user.username = form.username.data user.email = form.email.data user.save() redirect('register') return render_response('register.html', form=form) ``` -------------------------------- ### Form Inheritance Example Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md Forms can inherit from other forms. Fields from parent forms are included, and re-declared fields in a subclass will obscure the original. ```python class PastebinEdit(Form): language = SelectField('Programming Language', choices=PASTEBIN_LANGUAGES) code = TextAreaField() class PastebinEntry(PastebinEdit): name = StringField('User Name') ``` -------------------------------- ### Assign Custom Widget to SelectMultipleField Source: https://github.com/pallets-eco/wtforms/blob/main/docs/widgets.md Example of assigning the custom `select_multi_checkbox` widget to a SelectMultipleField in a WTForms form. ```python from wtforms import Form, SelectMultipleField my_choices = [('a', 'A'), ('b', 'B')] class TestForm(Form): tester = SelectMultipleField(choices=my_choices, widget=select_multi_checkbox) ``` -------------------------------- ### Handle File Uploads with WTForms FileField Source: https://github.com/pallets-eco/wtforms/blob/main/docs/faq.md WTForms provides a FileField for rendering file input widgets. Framework-specific handling of the uploaded file is required. Use `form.image.name` to get the correct input name. ```python class MyForm(Form): image = FileField() def my_view(request): form = MyForm(request.POST) file_wrapper = request.FILES[form.image.name] # Do things with your file wrapper now ``` -------------------------------- ### Define Custom IP Address CSRF Class Source: https://github.com/pallets-eco/wtforms/blob/main/docs/csrf.md Implement a custom CSRF class that generates a token based on the user's IP address. This example is for illustration and not recommended for production due to its deterministic nature. ```python from wtforms.csrf.core import CSRF from hashlib import md5 SECRET_KEY = '1234567890' class IPAddressCSRF(CSRF): """ Generate a CSRF token based on the user's IP. I am probably not very secure, so don't use me. """ def setup_form(self, form): self.csrf_context = form.meta.csrf_context return super(IPAddressCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token): token = md5(SECRET_KEY + self.csrf_context).hexdigest() return token def validate_csrf_token(self, form, field): if field.data != field.current_token: raise ValueError('Invalid CSRF') ``` -------------------------------- ### Django Template for Rendering Form Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Example of rendering a WTForms form within a Django template using the `form_field` tag. This tag facilitates passing keyword arguments for HTML attributes. ```html+django {% load wtforms %}
{{ form.username.label }}: {% form_field form.username class="css_class" %}
{{ form.password.label }}: {{ form.password }}
``` -------------------------------- ### SelectField with Custom Enum Labels Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Customize the display labels for Enum choices by providing a `label` callable to `Choice.from_enum()`. This example formats the Enum member name to title case. ```python Choice.from_enum(Color, label=lambda item: item.name.title()) ``` -------------------------------- ### SelectField with Custom Coerce Function Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Use the `coerce` parameter to specify a function that converts submitted string values to the desired Python type. This example handles converting the string 'None' to a Python None object. ```python def coerce_none(value): if value == 'None': return None return value class NonePossible(Form): my_select_field = SelectField('Select an option', choices=[ Choice('1', 'Option 1'), Choice('2', 'Option 2'), Choice('None', 'No option'), ], coerce=coerce_none) ``` -------------------------------- ### Initialize a New Translation Catalog Source: https://github.com/pallets-eco/wtforms/blob/main/src/wtforms/locale/README.md Use this command to create a new translation catalog for a specific locale. This sets up the necessary directory structure and template files. ```bash pybabel init --input-file src/wtforms/locale/wtforms.pot --output-dir src/wtforms/locale --domain wtforms --locale ``` -------------------------------- ### Extend WTForms Forms via Subclassing Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Demonstrates form inheritance by creating a ProfileForm and then an AdminProfileForm that extends it, adding new fields and overriding existing ones. ```default class ProfileForm(Form): birthday = DateTimeField('Your Birthday', format='%m/%d/%y') signature = TextAreaField('Forum Signature') class AdminProfileForm(ProfileForm): username = StringField('Username', [validators.Length(max=40)]) level = IntegerField('User Level', [validators.NumberRange(min=0, max=10)]) ``` -------------------------------- ### Import Widget Utilities Source: https://github.com/pallets-eco/wtforms/blob/main/docs/widgets.md Import necessary utilities for building custom widgets, including HTML escaping and parameter formatting. ```python from markupsafe import Markup, escape from wtforms.widgets import html_params ``` -------------------------------- ### Explore WTForms Form Structure in Console Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Instantiate a form and access its fields via dictionary or attribute style. Inspect `data` and `errors` properties to understand form state and validation results. ```python >>> from wtforms import Form, StringField, validators >>> class UsernameForm(Form): ... username = StringField('Username', [validators.Length(min=5)], default='test') ... >>> form = UsernameForm() >>> form['username'] >>> form.username.data 'test' >>> form.validate() False >>> form.errors {'username': ['Field must be at least 5 characters long.']} ``` ```python >>> form2 = UsernameForm(username='Robert') >>> form2.data {'username': 'Robert'} >>> form2.validate() True ``` -------------------------------- ### Instantiate and Use a Form Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md Instantiate a form by passing request data and optionally an ORM object. The ORM object is used to populate default field values. ```python def edit_article(request): article = Article.get(...) form = MyForm(request.POST, article) ``` -------------------------------- ### Define a basic WTForms Registration Form Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Define a simple registration form with username, email, and rules acceptance fields. Includes validators for length and input requirement. ```default from wtforms import Form, BooleanField, StringField, validators class RegistrationForm(Form): username = StringField('Username', [validators.Length(min=4, max=25)]) email = StringField('Email Address', [validators.Length(min=6, max=35)]) accept_rules = BooleanField('I accept the site rules', [validators.InputRequired()]) ``` -------------------------------- ### Compile Translation Catalogs Source: https://github.com/pallets-eco/wtforms/blob/main/src/wtforms/locale/README.md Compiles the .po translation files into a binary format for use by the application. This command also shows statistics about translation completeness. ```bash $ pybabel compile --directory src/wtforms/locale --domain wtforms --statistics ``` -------------------------------- ### Configure CSRF Implementation in Meta Source: https://github.com/pallets-eco/wtforms/blob/main/docs/csrf.md Set up CSRF protection by defining CSRF-related options within the Meta class of your base form. This includes enabling CSRF, specifying the implementation class, and providing a secret key if required by the chosen implementation. ```default from somemodule import SomeCSRF class MyBaseForm(Form): class Meta: csrf = True # Enable CSRF csrf_class = SomeCSRF # Set the CSRF implementation csrf_secret = b'foobar' # Some implementations need a secret key. # Any other CSRF settings here. ``` -------------------------------- ### WTForms Data Population Precedence Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Demonstrates the order of precedence for populating form data: POST data, `obj` argument, and keyword arguments. Reserved names like `formdata`, `obj`, and `prefix` cannot be overridden by keyword arguments. ```python def change_username(request): user = request.current_user form = ChangeUsernameForm(request.POST, user, username='silly') if request.method == 'POST' and form.validate(): user.username = form.username.data user.save() return redirect('change_username') return render_response('change_username.html', form=form) ``` -------------------------------- ### Customizing Form Behavior with Meta Source: https://github.com/pallets-eco/wtforms/blob/main/docs/meta.md Use a class Meta to customize options for default behaviors, such as CSRF protection and localization settings. ```python class MyForm(Form): class Meta: csrf = True locales = ('en_US', 'en') name = StringField(...) # and so on... ``` -------------------------------- ### Edit Existing Object with WTForms Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Instantiate a form with POST data and an existing object to pre-populate and edit it. Use `populate_obj` to save changes back to the object. ```python def edit_profile(request): user = request.current_user form = ProfileForm(request.POST, user) if request.method == 'POST' and form.validate(): form.populate_obj(user) user.save() redirect('edit_profile') return render_response('edit_profile.html', form=form) ``` -------------------------------- ### Update Existing Translation Catalogs Source: https://github.com/pallets-eco/wtforms/blob/main/src/wtforms/locale/README.md Propagates changes from the updated template catalog (.pot file) into all existing locale catalogs (.po files). ```bash pybabel update --input-file src/wtforms/locale/wtforms.pot --output-dir src/wtforms/locale --domain wtforms ``` -------------------------------- ### Define a Basic Form Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md Define a form by subclassing `Form` and declaring fields as class attributes. Use validators to enforce input rules. ```python class MyForm(Form): first_name = StringField('First Name', validators=[validators.input_required()]) last_name = StringField('Last Name', validators=[validators.optional()]) ``` -------------------------------- ### Dynamic Form Composition with WTForms Source: https://github.com/pallets-eco/wtforms/blob/main/docs/specific_problems.md Dynamically create or modify a form in your view by creating internal subclasses and using setattr. This is useful for forms where fields are determined at runtime. ```python def my_view(): class F(MyBaseForm): pass F.username = StringField('username') for name in iterate_some_model_dynamically(): setattr(F, name, StringField(name.title())) form = F(request.POST, ...) # do view stuff ``` -------------------------------- ### Implement a Custom Translations Provider Source: https://github.com/pallets-eco/wtforms/blob/main/docs/i18n.md Create a custom translations object with `gettext` and `ngettext` methods to handle translation of built-in WTForms strings. This object can be specified in the form's `Meta` class. ```python from mylibrary import ugettext, ungettext from wtforms import Form class MyTranslations(object): def gettext(self, string): return ugettext(string) def ngettext(self, singular, plural, n): return ungettext(singular, plural, n) class MyBaseForm(Form): class Meta: def get_translations(self, form): return MyTranslations() ``` -------------------------------- ### Configure Built-in Translations with Locales Source: https://github.com/pallets-eco/wtforms/blob/main/docs/i18n.md Pass locale languages to the `meta` argument in the form constructor to enable WTForms' built-in translations for default validator messages and coercion errors. ```python form = MyForm(request.form, meta={'locales': ['en_US', 'en']}) ``` -------------------------------- ### SelectField with Static Choices Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Define a SelectField with a predefined list of choices. Each choice is a tuple of value and label. ```python class PastebinEntry(Form): language = SelectField('Programming Language', choices=[ Choice('cpp', 'C++'), Choice('py', 'Python'), Choice('text', 'Plain Text'), ]) ``` -------------------------------- ### Translate User-Provided Messages with Lazy Proxies Source: https://github.com/pallets-eco/wtforms/blob/main/docs/i18n.md Use lazy proxies like `ugettext_lazy` to defer translation of user-provided strings until rendering or validation time. This allows for locale changes before interpolation. ```python from somelibrary import ugettext_lazy as _ from wtforms import Form, StringField, IntegerField, validators as v class RegistrationForm(Form): name = StringField(_('Name'), [v.InputRequired(_('Please provide your name'))]) age = IntegerField( _('Age'), [v.NumberRange(min=12, message=_('Must be at least %(min)d years old.'))] ) ``` -------------------------------- ### Form Validation and Data Population Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md This snippet shows a common pattern for handling form submissions: validating data, populating an object, saving it, and redirecting on success. It gates validation to avoid errors when no POST data is present. ```python if request.POST and form.validate(): form.populate_obj(article) article.save() return redirect('/articles') ``` -------------------------------- ### WTForms FieldList and FormField for Nested Objects Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Use `FieldList` with `FormField` to handle collections of nested objects. The `obj` argument and `populate_obj` method facilitate data binding for lists of items. ```python class ItemForm(Form): name = StringField() quantity = IntegerField() class CartForm(Form): items = FieldList(FormField(ItemForm)) form = CartForm(request.form, obj=cart) # cart.items == [item1, item2, ...] if form.validate(): form.populate_obj(cart) ``` -------------------------------- ### Extract Translatable Strings Source: https://github.com/pallets-eco/wtforms/blob/main/src/wtforms/locale/README.md Extracts translatable strings from the WTForms source code to update the template catalog (.pot file). Ensure copyright and project details are accurate. ```bash pybabel extract --copyright-holder="WTForms Team" --project="WTForms" --version="$(python -c 'import wtforms; print(wtforms.__version__)')" --output-file src/wtforms/locale/wtforms.pot src/wtforms ``` -------------------------------- ### SelectField with Optgroup Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Use SelectChoice to group options within an tag in the HTML select element. ```python class PastebinEntry(Form): language = SelectField('Programming Language', choices=[ SelectChoice('cpp', 'C++', optgroup='Compiled'), SelectChoice('rs', 'Rust', optgroup='Compiled'), SelectChoice('py', 'Python', optgroup='Interpreted'), SelectChoice('text', 'Plain Text'), ]) ``` -------------------------------- ### Define Form with Basic Validators Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Define a form with StringField and apply Length and Email validators. These validators check the input against specified criteria. ```python class ChangeEmailForm(Form): email = StringField('Email', [validators.Length(min=6, max=120), validators.Email()]) ``` -------------------------------- ### Jinja2 Template for Displaying All Form Errors Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Shows how to display all form errors in a single list at the top of the form using Jinja2. It iterates through the form's errors dictionary and formats them with field labels. ```html+jinja {% if form.errors %}
    {% for field_name, field_errors in form.errors|dictsort if field_errors %} {% for error in field_errors %}
  • {{ form[field_name].label }}: {{ error }}
  • {% endfor %} {% endfor %}
{% endif %} ``` -------------------------------- ### Render Form Field by Coercing to String Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Render a form field by simply converting it to a string. This produces the basic HTML input tag for the field. ```python >>> from wtforms import Form, StringField >>> class SimpleForm(Form): ... content = StringField('content') ... >>> form = SimpleForm(content='foobar') >>> str(form.content) Markup('') ``` -------------------------------- ### Render Form Field with HTML Attributes Source: https://github.com/pallets-eco/wtforms/blob/main/docs/crash_course.md Render a form field by calling it like a function, passing keyword arguments that become HTML attributes. This allows customization of the input tag. ```python >>> form.content(style="width: 200px;", class_="bar") Markup('') ``` -------------------------------- ### SelectField with Dynamic Choices Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Provide a callable to the choices parameter for dynamic option generation. The callable is re-evaluated on each form instantiation. ```python def available_groups(): return [Choice(g.id, g.name) for g in Group.query.order_by('name')] class UserDetails(Form): group_id = SelectField('Group', coerce=int, choices=available_groups) ``` -------------------------------- ### Create Form and View with Custom CSRF Source: https://github.com/pallets-eco/wtforms/blob/main/docs/csrf.md Define a WTForms form that utilizes the custom CSRF class and a view function to handle form submission and validation, including CSRF token checking. ```python class RegistrationForm(Form): class Meta: csrf = True csrf_class = IPAddressCSRF name = StringField('Your Name') email = StringField('Email', [validators.email()]) def register(request): form = RegistrationForm( request.POST, meta={'csrf_context': request.ip} ) if request.method == 'POST' and form.validate(): pass # We're all good, create a user or whatever it is you do elif form.csrf_token.errors: pass # If we're here we suspect the user of cross-site request forgery else: pass # Any other errors return render('register.html', form=form) ``` -------------------------------- ### Define Forms with CSRF Enabled Source: https://github.com/pallets-eco/wtforms/blob/main/docs/csrf.md Create your form classes by subclassing a base form that has CSRF enabled in its Meta configuration. This ensures that all forms inheriting from the base will have CSRF protection active by default. ```python class UserForm(MyBaseForm): name = StringField() age = IntegerField() def view(): form = UserForm(request.POST) if request.POST and form.validate(): pass # Form is valid and CSRF succeeded return render('user.html', form=form) ``` -------------------------------- ### Configurable Validator Factory Source: https://github.com/pallets-eco/wtforms/blob/main/docs/validators.md Create a factory function that returns a configurable validator. This allows validators to be parameterized, like setting minimum and maximum lengths. ```python def length(min=-1, max=-1): message = 'Must be between %d and %d characters long.' % (min, max) def _length(form, field): l = field.data and len(field.data) or 0 if l < min or max != -1 and l > max: raise ValidationError(message) return _length class MyForm(Form): name = StringField('Name', [InputRequired(), length(max=50)]) ``` -------------------------------- ### Rendering Form and Errors in Template Source: https://github.com/pallets-eco/wtforms/blob/main/docs/forms.md This snippet illustrates how to pass a form object to a template for rendering fields and displaying validation errors. This is typically done when form submission fails or no POST data exists. ```python return render('edit.html', form=form, article=article) ``` -------------------------------- ### Dynamic Choices for DataList Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Provide a callable to the `choices` argument of DataList to dynamically generate suggestions. The callable can accept the field object for server-side filtering. ```python DataList(lambda field: search(field.data)) ``` -------------------------------- ### Field Base Class Source: https://github.com/pallets-eco/wtforms/blob/main/docs/fields.md Details the WTForms Field base class, its construction, validation, data access, rendering, and properties. ```APIDOC ## The Field base class ### *class* wtforms.fields.Field Stores and processes data, and generates HTML for a form field. Field instances contain the data of that instance as well as the functionality to render it within your Form. They also contain a number of properties which can be used within your templates to render the field and label. **Construction** Built-in field processing messages can be customized per field with `invalid_value_message=`. **Validation** To validate the field, call its validate method, providing a form and any extra validators needed. To extend validation behaviour, override pre_validate or post_validate. #### errors If validate encounters any errors, they will be inserted into this list. **Data access and processing** To handle incoming data from python, override process_data. Similarly, to handle incoming data from the outside, override process_formdata. #### data Contains the resulting (sanitized) value of calling either of the process methods. Note that it is not HTML escaped when using in templates. #### raw_data If form data is processed, is the valuelist given from the formdata wrapper. Otherwise, raw_data will be None. #### object_data This is the data passed from an object or from kwargs to the field, stored unmodified. This can be used by templates, widgets, validators as needed (for comparison, for example) **Rendering** To render a field, simply call it, providing any values the widget expects as keyword arguments. Usually the keyword arguments are used for extra HTML attributes. **Message Translations** **Properties** #### name The HTML form name of this field. This is the name as defined in your Form prefixed with the prefix passed to the Form constructor. #### short_name The un-prefixed name of this field. #### id The HTML ID of this field. If unspecified, this is generated for you to be the same as the field name. #### label This is a [`Label`](#wtforms.fields.Label) instance which when evaluated as a string returns an HTML [