You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
4.3 KiB
110 lines
4.3 KiB
.. _ref-contrib-formtools-form-preview: |
|
|
|
============ |
|
Form preview |
|
============ |
|
|
|
.. module:: django.contrib.formtools |
|
:synopsis: Displays an HTML form, forces a preview, then does something |
|
with the submission. |
|
|
|
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 :class:`django.forms.Form` subclass that you define, this |
|
application takes care of the following workflow: |
|
|
|
1. Displays the form as HTML on a Web page. |
|
2. Validates the form data when it's submitted via POST. |
|
a. If it's valid, displays a preview page. |
|
b. If it's not valid, redisplays the form with error messages. |
|
3. When the "confirmation" form is submitted from the preview page, calls |
|
a hook that you define -- a |
|
:meth:`~django.contrib.formtools.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`` |
|
========================== |
|
|
|
1. Point Django at the default FormPreview templates. There are two ways to |
|
do this: |
|
|
|
* Add ``'django.contrib.formtools'`` to your |
|
:setting:`INSTALLED_APPS` setting. This will work if your |
|
:setting:`TEMPLATE_LOADERS` setting includes the |
|
``app_directories`` template loader (which is the case by |
|
default). See the :ref:`template loader docs <template-loaders>` |
|
for more. |
|
|
|
* Otherwise, determine the full filesystem path to the |
|
:file:`django/contrib/formtools/templates` directory, and add that |
|
directory to your :setting:`TEMPLATE_DIRS` setting. |
|
|
|
2. Create a :class:`~django.contrib.formtools.FormPreview` subclass that |
|
overrides the :meth:`~django.contrib.formtools.FormPreview.done()` |
|
method:: |
|
|
|
from django.contrib.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 :class:`~django.http.HttpRequest` object and a |
|
dictionary of the form data after it has been validated and cleaned. |
|
It should return an :class:`~django.http.HttpResponseRedirect` that |
|
is the end result of the form being submitted. |
|
|
|
3. Change your URLconf to point to an instance of your |
|
:class:`~django.contrib.formtools.FormPreview` subclass:: |
|
|
|
from myapp.preview import SomeModelFormPreview |
|
from myapp.forms import SomeModelForm |
|
from django import forms |
|
|
|
...and add the following line to the appropriate model in your URLconf:: |
|
|
|
(r'^post/$', SomeModelFormPreview(SomeModelForm)), |
|
|
|
where ``SomeModelForm`` is a Form or ModelForm class for the model. |
|
|
|
4. Run the Django server and visit :file:`/post/` in your browser. |
|
|
|
``FormPreview`` classes |
|
======================= |
|
|
|
.. class:: FormPreview |
|
|
|
A :class:`~django.contrib.formtools.FormPreview` class is a simple Python class |
|
that represents the preview workflow. |
|
:class:`~django.contrib.formtools.FormPreview` classes must subclass |
|
``django.contrib.formtools.preview.FormPreview`` and override the |
|
:meth:`~django.contrib.formtools.FormPreview.done()` method. They can live |
|
anywhere in your codebase. |
|
|
|
``FormPreview`` templates |
|
========================= |
|
|
|
By default, the form is rendered via the template :file:`formtools/form.html`, |
|
and the preview page is rendered via the template :file:`formtools/preview.html`. |
|
These values can be overridden for a particular form preview by setting |
|
:attr:`~django.contrib.formtools.FormPreview.preview_template` and |
|
:attr:`~django.contrib.formtools.FormPreview.form_template` attributes on the |
|
FormPreview subclass. See :file:`django/contrib/formtools/templates` for the |
|
default templates.
|
|
|