Forms

Ferris provides HTML form support using the wtforms library. Please consult the wtforms documentation for a list of field types and advanced form usage. This documentation covers how to use wtforms in conjuction with Ferris.

Model Form

Usually you’ll be using forms to interact with model data. This sort of use is called a Model Form. A model can have any number of forms; for example, different forms for different workflow steps.

You can generate a model form automatically using model_form():

ferris.core.forms.model_form(model, base_class=<class 'wtforms.form.Form'>, only=None, exclude=None, field_args=None, converter=None)

Creates and returns a dynamic wtforms.Form class for a given ndb.Model class. The form class can be used as it is or serve as a base for extended form classes, which can then mix non-model related fields, subforms with other model forms, among other possibilities.

Parameters:
  • model – The ndb.Model class to generate a form for.
  • base_class – Base form class to extend from. Must be a wtforms.Form subclass.
  • only – An optional iterable with the property names that should be included in the form. Only these properties will have fields.
  • exclude – An optional iterable with the property names that should be excluded from the form. All other properties will have fields.
  • field_args – An optional dictionary of field names mapping to keyword arguments used to construct each field object.
  • converter – A converter to generate the fields based on the model properties. If not set, ModelConverter is used.

For example:

CatInfoForm = model_form(Cat)

This is exactly what Scaffolding does if you do not explicitly specify a model form.

You can also add additional fields to your form just like any other form:

class CatInfoForm(model_form(Cat)):
    claws = wtforms.fields.BooleanField()

Tip

All of the standard arguments of model_form work, including only, exclude, and most importantly, field_args. Check out the associated documentation for wtforms.

When using Scaffolding, you can specify the Model Form to use by setting Scaffold.ModelForm or self.scaffold.ModelForm.

For example:

def Cats(Controller):
    class Meta:
        ...

    Class Scaffold:
        ModelForm = CatInfoForm

or:

def add(self):
    self.scaffold.ModelForm = CatInfoForm
    return scaffold.add(self)

Using Forms in Controller

Once you have a form class, you can process form data into your form using Request Parsers.

For example:

def contact_us(self):
    form = ContactUsForm()
    self.parse_request(container=form)

    if self.request.method != 'GET' and form.validate():
        return form.message

Using Forms in Views

Since Ferris uses Jinja2 and wtforms, all of the same principles in the wtforms documentation apply.

Ferris does however provide one useful macro in macros/form.html:

FormMacros.form_field(form, field, container_element='div')

Generates a bootstrap style form control with error message and help block.

For example:

{% import "macros/form.html" as f with context %}

<form>
    {{f.form_field(form, form.title)}}
    {{f.form_field(form, form.description)}}
</form>