mirror of
https://github.com/django/django.git
synced 2024-12-26 11:06:07 +00:00
98 lines
3.8 KiB
Plaintext
98 lines
3.8 KiB
Plaintext
|
============
|
||
|
Form 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.newforms.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 ``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 ``INSTALLED_APPS``
|
||
|
setting. This will work if your ``TEMPLATE_LOADERS`` setting includes
|
||
|
the ``app_directories`` template loader (which is the case by
|
||
|
default). See the `template loader docs`_ for more.
|
||
|
|
||
|
* Otherwise, determine the full filesystem path to the
|
||
|
``django/contrib/formtools/templates`` directory, and add that
|
||
|
directory to your ``TEMPLATE_DIRS`` setting.
|
||
|
|
||
|
2. Create a ``FormPreview`` subclass that overrides the ``done()`` method::
|
||
|
|
||
|
from django.contrib.formtools 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 ``HttpRequest`` object and a dictionary of the form
|
||
|
data after it has been validated and cleaned. It should return an
|
||
|
``HttpResponseRedirect`` that is the end result of the form being
|
||
|
submitted.
|
||
|
|
||
|
3. Change your URLconf to point to an instance of your ``FormPreview``
|
||
|
subclass::
|
||
|
|
||
|
from myapp.preview import SomeModelFormPreview
|
||
|
from myapp.models import SomeModel
|
||
|
from django import newforms as forms
|
||
|
|
||
|
...and add the following line to the appropriate model in your URLconf::
|
||
|
|
||
|
(r'^post/$', SomeModelFormPreview(forms.models.form_for_model(SomeModel))),
|
||
|
|
||
|
Or, if you already have a Form class defined for the model::
|
||
|
|
||
|
(r'^post/$', SomeModelFormPreview(SomeModelForm)),
|
||
|
|
||
|
4. Run the Django server and visit ``/post/`` in your browser.
|
||
|
|
||
|
.. _template loader docs: ../templates_python/#loader-types
|
||
|
|
||
|
``FormPreview`` classes
|
||
|
=======================
|
||
|
|
||
|
A ``FormPreview`` class is a simple Python class that represents the preview
|
||
|
workflow. ``FormPreview`` classes must subclass
|
||
|
``django.contrib.formtools.preview.FormPreview`` and override the ``done()``
|
||
|
method. They can live anywhere in your codebase.
|
||
|
|
||
|
``FormPreview`` templates
|
||
|
=========================
|
||
|
|
||
|
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
|
||
|
``preview_template`` and ``form_template`` attributes on the FormPreview
|
||
|
subclass. See ``django/contrib/formtools/templates`` for the default templates.
|