Forms

Forms provide the highest level API in WTForms. They contain your field definitions, delegate validation, take input, aggregate errors, and in general function as the glue holding everything together.

The Form class

class wtforms.form.Form(formdata=None, obj=None, prefix='', **kwargs)

Declarative Form base class. Extends BaseForm’s core behaviour allowing fields to be defined on Form subclasses as class attributes.

In addition, form and instance input data are taken at construction time and passed to process().

Construction

__init__(formdata=None, obj=None, prefix='', **kwargs)
Parameters:
  • formdata – Used to pass data coming from the enduser, usually request.POST or equivalent.
  • obj – If formdata has no data for a field, the form will try to get it from the passed object.
  • prefix – If provided, all fields will have their name prefixed with the value.
  • **kwargs – If neither formdata or obj contains a value for a field, the form will assign the value of a matching keyword argument to the field, if provided.

Properties

data

A dict containing the data for each field.

Note that this is generated each time you access the property, so care should be taken when using it, as it can potentially be very expensive if you repeatedly access it. Typically used if you need to iterate all data in the form. If you just need to access the data for known fields, you should use form.<field>.data, not this proxy property.

errors

A dict containing a list of errors for each field. Empty if the form hasn’t been validated, or there were no errors.

Note that this is a lazy property, and will only be generated when you first access it. If you call validate() after accessing it, the cached result will be invalidated and regenerated on next access.

Methods

validate()
Validates the form by calling validate on each field, passing any extra Form.validate_<fieldname> validators to the field validator.
populate_obj(obj)

Populates the attributes of the passed obj with data from the form’s fields.

Note:This is a destructive operation; Any attribute with the same name as a field will be overridden. Use with caution.

One common usage of this is an edit profile view:

def edit_profile(request):
    user = User.objects.get(pk=request.session['userid'])
    form = EditProfileForm(request.POST, obj=user)

    if request.POST and form.validate():
        form.populate_obj(user)
        user.save()
        return redirect('/home')
    return render_to_response('edit_profile.html', form=form)

In the above example, because the form isn’t directly tied to the user object, you don’t have to worry about any dirty data getting onto there until you’re ready to move it over.

__iter__()

Iterate form fields in their order of definition on the form.

{% for field in form %}
    <tr>
        <th>{{ field.label }}</th>
        <td>{{ field }}</td>
    </tr>
{% endfor %}
__contains__(item)
Returns True if the named field is a member of this form.

Defining Forms

To define a form, one makes a subclass of Form and defines the fields declaratively as class attributes:

class MyForm(Form):
    first_name = TextField(u'First Name', validators=[validators.required()])
    last_name  = TextField(u'Last Name', validators=[validators.optional()])

Field names can be any valid python identifier, with the following restrictions:

  • Field names are case-sensitive.
  • Field names may not begin with “_” (underscore)
  • Field names may not begin with “validate”

Form Inheritance

Forms may subclass other forms as needed. The new form will contain all fields of the parent form, as well as any new fields defined on the subclass. A field name re-used on a subclass causes the new definition to obscure the original.

class PastebinEdit(Form):
    language = SelectField(u'Programming Language', choices=PASTEBIN_LANGUAGES)
    code     = TextAreaField()

class PastebinEntry(PastebinEdit):
    name = TextField(u'User Name')

In-line Validators

In order to provide custom validation for a single field without needing to write a one-time-use validator, validation can be defined inline by defining a method with the convention validate_fieldname:

class SignupForm(Form):
    age = IntegerField(u'Age')

    def validate_age(form, field):
        if field.data < 13:
            raise ValidationError("We're sorry, you must be 13 or older to register")

Using Forms

A form is most often constructed in the controller code for handling an action, with the form data wrapper from the framework passed to its constructor, and optionally an ORM object. The constructed form can then validate any input data and generate errors if invalid. The form object can then be passed along to template code to render the form fields along with any errors which occurred.

Low-Level API

Warning

This section is provided for completeness; and is aimed at authors of complementary libraries and those looking for very special behaviors. Don’t use BaseForm unless you know exactly why you are using it.

For those looking to customize how WTForms works, for libraries or special applications, it might be worth using the BaseForm class. BaseForm is the parent class of Form, and most of the implementation logic from Form is actually handled by BaseForm.

The major difference on the surface between BaseForm and Form is that fields are not defined declaratively on a subclass of BaseForm. Instead, you must pass a dict of fields to the constructor. Likewise, you cannot add fields by inheritance. In addition, BaseForm does not provide: sorting fields by definition order, or inline validate_foo validators. Because of this, for the overwhelming majority of uses we recommend you use Form instead of BaseForm in your code.

What BaseForm provides is a container for a collection of fields, which it will bind at instantiation, and hold in an internal dict. Dict-style access on a BaseForm instance will allow you to access (and modify) the enclosed fields.

class wtforms.form.BaseForm(fields, prefix='')

Base Form Class. Provides core behaviour like field construction, validation, and data and error proxying.

Construction

__init__(fields, prefix='')
Parameters:
  • fields – A dict or sequence of 2-tuples of partially-constructed fields.
  • prefix – If provided, all fields will have their name prefixed with the value.
form = BaseForm({
    'name': TextField(),
    'customer.age': IntegerField("Customer's Age")
})

Because BaseForm does not require field names to be valid identifiers, they can be most any python string. We recommend keeping it simple to avoid incompatibility with browsers and various form input frameworks where possible.

Properties

data
see Form.data
errors
see Form.errors

Methods

process(formdata=None, obj=None, **kwargs)

Take form, object data, and keyword arg input and have the fields process them.

Parameters:
  • formdata – Used to pass data coming from the enduser, usually request.POST or equivalent.
  • obj – If formdata has no data for a field, the form will try to get it from the passed object.
  • **kwargs – If neither formdata or obj contains a value for a field, the form will assign the value of a matching keyword argument to the field, if provided.

Since BaseForm does not take its data at instantiation, you must call this to provide form data to the enclosed fields. Accessing the field’s data before calling process is not recommended.

validate(extra_validators=None)

Validates the form by calling validate on each field.

Parameter:extra_validators – If provided, is a dict mapping field names to a sequence of callables which will be passed as extra validators to the field’s validate method.

Returns True if no errors occur.

__iter__()

Iterate form fields in arbitrary order

Unlike Form, fields are not iterated in definition order, but rather in whatever order the dict decides to yield them.

__contains__(item)
Returns True if the named field is a member of this form.
__getitem__(name)
Dict-style access to this form’s fields.
__setitem__(name, value)

Bind a field to this form.

form['openid.name'] = TextField()

Fields can be added and replaced in this way, but this must be done before process() is called, or the fields will not have the opportunity to receive input data. Similarly, changing fields after validate() will have undesired effects.

__delitem__(name)

Remove a field from this form.

The same caveats apply as with __setitem__().