Navigation

In the previous chapter we demonstrated how to use Deform to render a complete
form, including the input fields, the buttons, and so forth. We used the
deform.Field.render() method, and injected the resulting HTML snippet
into a larger HTML page in our application. That is an effective and quick way
to put a form on a page, but sometimes you need more fine-grained control over
the way form HTML is rendered. For example, you may need form elements to be
placed on the page side-by-side or you might need the form’s styling to be
radically different than the form styling used by the default rendering of
Deform forms. Often it’s easier to use Deform slightly differently, where you
do more work yourself to draw the form within a template, and only use Deform
for some of its features. We refer to this as “retail form rendering”.

We feed the schema into a template as the form value. It doesn’t matter
what kind of templating system you use to do this, but this example will use
ZPT. Below, the name form refers to the form we just created above:

You can use as little or as much of the Deform Field API to draw the widget as
you like. The above examples use the deform.Field.serialize() method,
which is an easy way to let Deform draw the field HTML, but you can draw it
yourself instead if you like, and just rely on the field object for its
validation errors (if any). Note that the serialize method accepts
arbitrary keyword arguments that will be passed as top-level arguments to the
Deform widget templates, so if you need to change how a particular widget is
rendered without doing things completely by hand, you may want to take a look
at the existing widget template and see if your need has been anticipated.

In the POST handler for the form, just do things like we did in the last
chapter, except if validation fails, just re-render the template with the same
form object.

controls=request.POST.items()# get the form controlstry:appstruct=form.validate(controls)# call validateexceptValidationFailurease:# catch the exception# .. rerender the form .. its field's .error attributes# will be set

It is also possible to pass an appstruct argument to the
deform.Form constructor to create “edit forms”. Form/field objects
are initialized with this appstruct (recursively) when they’re created. This
means that accessing form.cstruct will return the current set of rendering
values. This value is reset during validation, so after a validation is done
you can re-render the form to show validation errors.

Note that existing Deform widgets are all built using “retail mode” APIs, so if
you need examples, you can look at their templates.