4.3 KiB
Form preview
formtools.preview
Django comes with an optional "form preview" application that helps automate the following workflow:
"Display an HTML form, force a preview, then do something with the submission."
To force a preview of a form submission, all you have to do is write a short Python class.
Overview
Given a ~django.forms.Form subclass that you define, this
application takes care of the following workflow:
- Displays the form as HTML on a Web page.
- Validates the form data when it's submitted via POST.
- If it's valid, displays a preview page.
- If it's not valid, redisplays the form with error messages.
- When the "confirmation" form is submitted from the preview page,
calls a hook that you define -- a
~FormPreview.done()method that gets passed the valid data.
The framework enforces the required preview by passing a shared-secret hash to the preview page via hidden form fields. If somebody tweaks the form parameters on the preview page, the form submission will fail the hash-comparison test.
How to use FormPreview
Point Django at the default FormPreview templates. There are two ways to do this:
Add
'formtools'to yourINSTALLED_APPSsetting.This will work if your
TEMPLATESsetting includes theapp_directoriestemplate loader (which is the case by default).See the
template loader docs <template-loaders>for more.Otherwise, determine the full filesystem path to the
formtools/templatesdirectory and add that directory to yourDIRS <TEMPLATES-DIRS>option in theTEMPLATESsetting.
Create a
~FormPreviewsubclass that overrides thedone()method:from django.http import HttpResponseRedirect from formtools.preview import FormPreview from myapp.models import SomeModel class SomeModelFormPreview(FormPreview): def done(self, request, cleaned_data): # Do something with the cleaned_data, then redirect # to a "success" page. return HttpResponseRedirect('/form/success')This method takes an
~django.http.HttpRequestobject and a dictionary of the form data after it has been validated and cleaned. It should return an~django.http.HttpResponseRedirectthat is the end result of the form being submitted.Change your URLconf to point to an instance of your
~FormPreviewsubclass:from django import forms from myapp.forms import SomeModelForm from myapp.preview import SomeModelFormPreview...and add the following line to the appropriate model in your URLconf:
url(r'^post/$', SomeModelFormPreview(SomeModelForm)),where
SomeModelFormis a Form or ModelForm class for the model.Run the Django server and visit
/post/in your browser.
FormPreview classes
A ~FormPreview
class is a simple Python class that represents the preview workflow.
~FormPreview classes
must subclass FormPreview and override the
done() method. They can live anywhere in your codebase.
FormPreview templates
FormPreview.form_template
FormPreview.preview_template
By default, the form is rendered via the template formtools/form.html, and the
preview page is rendered via the template formtools/preview.html.
These values can be overridden for a particular form preview by
setting ~FormPreview.preview_template and ~FormPreview.form_template
attributes on the FormPreview subclass. See formtools/templates for the
default templates.
Required methods
FormPreview.done
Optional methods
FormPreview.get_auto_id
FormPreview.get_initial
FormPreview.get_context
FormPreview.parse_params
FormPreview.process_preview
FormPreview.security_hash
FormPreview.failed_hash