CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-wtforms

Form validation and rendering for Python web development.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

forms.mddocs/

Forms and Processing

Core form functionality including form definition, data processing, validation, and object population. These classes provide the foundation for all form handling in WTForms.

Capabilities

Form Classes

The main form classes that provide declarative form definition and processing capabilities.

class Form:
    """
    Declarative form class with metaclass support for field definition.
    
    Parameters:
    - formdata: Input data from client (multidict interface like request.form)
    - obj: Object to populate fields from  
    - prefix: Optional prefix for all field names
    - data: Dict of field data to pre-populate
    - meta: Meta configuration overrides
    - **kwargs: Additional field data
    """
    def __init__(self, formdata=None, obj=None, prefix="", data=None, meta=None, **kwargs): ...
    
    def validate(self, extra_validators=None) -> bool:
        """
        Validate all fields and run validate_<fieldname> methods.
        
        Parameters:
        - extra_validators: Dict of field_name -> list of extra validators
        
        Returns:
        bool: True if all fields validate successfully
        """
    
    def populate_obj(self, obj):
        """
        Populate object attributes with form field data.
        
        Parameters:
        - obj: Object to populate (uses field names as attribute names)
        """
    
    def process(self, formdata=None, obj=None, data=None, extra_filters=None, **kwargs):
        """
        Process form data through all fields.
        
        Parameters:
        - formdata: Input data from client
        - obj: Object to populate fields from
        - data: Dict of field data
        - extra_filters: Additional data filters to apply
        - **kwargs: Additional field data
        """
    
    # Dict-like field access
    def __iter__(self): ...
    def __contains__(self, name) -> bool: ...
    def __getitem__(self, name) -> Field: ...
    def __setitem__(self, name, value): ...
    def __delitem__(self, name): ...
    
    # Properties
    data: dict  # Dict of all field data
    errors: dict  # Dict of field errors  
    form_errors: list  # Form-level validation errors

class BaseForm:
    """
    Base form class providing core form behavior without metaclass.
    
    Parameters:
    - fields: Dict or sequence of 2-tuples of partially-constructed fields
    - prefix: Optional prefix for all field names
    - meta: Meta instance for configuration
    """
    def __init__(self, fields, prefix="", meta=None): ...
    
    def validate(self, extra_validators=None) -> bool:
        """Validate all fields, returns True if all fields validate."""
    
    def populate_obj(self, obj):
        """Populate object attributes with form data."""
    
    def process(self, formdata=None, obj=None, data=None, extra_filters=None, **kwargs):
        """Process form data through all fields."""
    
    # Dict-like field access methods (same as Form)
    def __iter__(self): ...
    def __contains__(self, name) -> bool: ...
    def __getitem__(self, name) -> Field: ...
    def __setitem__(self, name, value): ...
    def __delitem__(self, name): ...
    
    # Properties
    data: dict  # Dict of all field data
    errors: dict  # Dict of field errors
    form_errors: list  # Form-level validation errors

Form Usage Examples

Basic Form Definition and Processing

from wtforms import Form, StringField, IntegerField, validators

class UserRegistrationForm(Form):
    username = StringField('Username', [
        validators.DataRequired(),
        validators.Length(min=4, max=25)
    ])
    email = StringField('Email Address', [
        validators.DataRequired(),
        validators.Email()
    ])
    age = IntegerField('Age', [
        validators.NumberRange(min=13, max=120)
    ])

# Process form submission
def handle_registration(request):
    form = UserRegistrationForm(formdata=request.form)
    
    if form.validate():
        # Create user object
        user = User()
        form.populate_obj(user)  # Sets user.username, user.email, user.age
        user.save()
        return redirect('/success')
    else:
        # Re-render form with errors
        return render_template('register.html', form=form)

Form with Object Population

def edit_user(request, user_id):
    user = User.get(user_id)
    form = UserRegistrationForm(formdata=request.form, obj=user)
    
    if form.validate():
        form.populate_obj(user)
        user.save()
        return redirect('/success')
    
    return render_template('edit_user.html', form=form)

Custom Validation Methods

class LoginForm(Form):
    username = StringField('Username', [validators.DataRequired()])
    password = StringField('Password', [validators.DataRequired()])
    
    def validate_username(self, field):
        """Custom validation method for username field."""
        if not User.exists(field.data):
            raise ValidationError('Username does not exist.')
    
    def validate_password(self, field):
        """Custom validation method for password field."""  
        user = User.get_by_username(self.username.data)
        if user and not user.check_password(field.data):
            raise ValidationError('Invalid password.')

Form with Prefixes

# Useful for multiple forms on one page
billing_form = AddressForm(formdata=request.form, prefix='billing')
shipping_form = AddressForm(formdata=request.form, prefix='shipping')

if billing_form.validate() and shipping_form.validate():
    # Process both forms
    pass

Dynamic Field Access

form = MyForm(formdata=request.form)

# Access fields dynamically
for field_name, field in form:
    print(f"Field {field_name}: {field.data}")

# Check if field exists
if 'username' in form:
    username_field = form['username']

# Access field data and errors
all_data = form.data  # {'username': 'john', 'email': 'john@example.com'}
all_errors = form.errors  # {'email': ['Invalid email address.']}

Advanced Form Patterns

Form Inheritance

class BaseUserForm(Form):
    username = StringField('Username', [validators.DataRequired()])
    email = StringField('Email', [validators.Email()])

class AdminUserForm(BaseUserForm):
    is_admin = BooleanField('Admin privileges')
    permissions = SelectMultipleField('Permissions', choices=[...])

Form Composition with FormField

class AddressForm(Form):
    street = StringField('Street')
    city = StringField('City')
    zipcode = StringField('Zip Code')

class UserForm(Form):
    name = StringField('Name')
    billing_address = FormField(AddressForm)
    shipping_address = FormField(AddressForm)

# Access nested data
form = UserForm(formdata=request.form)
if form.validate():
    billing_street = form.billing_address.street.data
    shipping_city = form.shipping_address.city.data

Error Handling

Form validation produces structured error information that can be used for display:

form = MyForm(formdata=request.form)
if not form.validate():
    # Field-level errors
    for field_name, field_errors in form.errors.items():
        for error in field_errors:
            print(f"Error in {field_name}: {error}")
    
    # Form-level errors (from validate_<fieldname> methods)
    for error in form.form_errors:
        print(f"Form error: {error}")
    
    # Individual field errors
    if form.username.errors:
        print("Username errors:", form.username.errors)

Install with Tessl CLI

npx tessl i tessl/pypi-wtforms

docs

csrf.md

fields.md

forms.md

i18n.md

index.md

validation.md

widgets.md

tile.json