Improve FormPreview docs to encompass more methods. Fix some cosmetic issues. Fixes issue #32.
This commit is contained in:
parent
ee8bb9f4f6
commit
659bdfd889
|
@ -9,7 +9,8 @@ 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."
|
||||
"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.
|
||||
|
@ -17,16 +18,18 @@ Python class.
|
|||
Overview
|
||||
=========
|
||||
|
||||
Given a :class:`django.forms.Form` subclass that you define, this
|
||||
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 ``done()`` method that gets passed the valid
|
||||
data.
|
||||
a hook that you define -- a :meth:`~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
|
||||
|
@ -39,20 +42,23 @@ How to use ``FormPreview``
|
|||
do this:
|
||||
|
||||
* Add ``'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.
|
||||
: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
|
||||
:file:`formtools/templates` directory, and add that
|
||||
directory to your :setting:`TEMPLATE_DIRS` setting.
|
||||
|
||||
2. Create a :class:`~formtools.preview.FormPreview` subclass that
|
||||
|
||||
2. Create a :class:`~FormPreview` subclass that
|
||||
overrides the ``done()`` method::
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
from formtools.preview import FormPreview
|
||||
from myapp.models import SomeModel
|
||||
|
||||
|
@ -69,12 +75,13 @@ How to use ``FormPreview``
|
|||
is the end result of the form being submitted.
|
||||
|
||||
3. Change your URLconf to point to an instance of your
|
||||
:class:`~formtools.preview.FormPreview` subclass::
|
||||
:class:`~FormPreview` subclass::
|
||||
|
||||
from myapp.preview import SomeModelFormPreview
|
||||
from myapp.forms import SomeModelForm
|
||||
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)),
|
||||
|
@ -88,10 +95,10 @@ How to use ``FormPreview``
|
|||
|
||||
.. class:: FormPreview
|
||||
|
||||
A :class:`~formtools.preview.FormPreview` class is a simple Python class
|
||||
A :class:`~FormPreview` class is a simple Python class
|
||||
that represents the preview workflow.
|
||||
:class:`~formtools.preview.FormPreview` classes must subclass
|
||||
``formtools.preview.FormPreview`` and override the ``done()``
|
||||
:class:`~FormPreview` classes must subclass
|
||||
``FormPreview`` and override the ``done()``
|
||||
method. They can live anywhere in your codebase.
|
||||
|
||||
``FormPreview`` templates
|
||||
|
@ -102,19 +109,30 @@ method. They can live anywhere in your codebase.
|
|||
|
||||
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:`~formtools.preview.FormPreview.preview_template` and
|
||||
:attr:`~formtools.preview.FormPreview.form_template` attributes on the
|
||||
FormPreview subclass. See :file:`django/contrib/formtools/templates` for the
|
||||
default templates.
|
||||
:attr:`~FormPreview.preview_template` and
|
||||
:attr:`~FormPreview.form_template` attributes on the
|
||||
FormPreview subclass. See :file:`formtools/templates` for the default templates.
|
||||
|
||||
Advanced ``FormPreview`` methods
|
||||
================================
|
||||
Required methods
|
||||
================
|
||||
|
||||
.. method:: FormPreview.process_preview()
|
||||
.. automethod:: FormPreview.done
|
||||
|
||||
Given a validated form, performs any extra processing before displaying the
|
||||
preview page, and saves any extra data in context.
|
||||
Optional methods
|
||||
================
|
||||
|
||||
By default, this method is empty. It is called after the form is validated,
|
||||
but before the context is modified with hash information and rendered.
|
||||
.. automethod:: FormPreview.get_auto_id
|
||||
|
||||
.. automethod:: FormPreview.get_initial
|
||||
|
||||
.. automethod:: FormPreview.get_context
|
||||
|
||||
.. automethod:: FormPreview.parse_params
|
||||
|
||||
.. automethod:: FormPreview.process_preview
|
||||
|
||||
.. automethod:: FormPreview.security_hash
|
||||
|
||||
.. automethod:: FormPreview.failed_hash
|
||||
|
|
|
@ -121,16 +121,16 @@ class FormPreview(object):
|
|||
def parse_params(self, *args, **kwargs):
|
||||
"""
|
||||
Given captured args and kwargs from the URLconf, saves something in
|
||||
self.state and/or raises Http404 if necessary.
|
||||
self.state and/or raises :class:`~django.http.Http404` if necessary.
|
||||
|
||||
For example, this URLconf captures a user_id variable:
|
||||
For example, this URLconf captures a user_id variable::
|
||||
|
||||
(r'^contact/(?P<user_id>\d{1,6})/$', MyFormPreview(MyForm)),
|
||||
|
||||
In this case, the kwargs variable in parse_params would be
|
||||
{'user_id': 32} for a request to '/contact/32/'. You can use that
|
||||
user_id to make sure it's a valid user and/or save it for later, for
|
||||
use in done().
|
||||
``{'user_id': 32}`` for a request to ``'/contact/32/'``. You can use
|
||||
that ``user_id`` to make sure it's a valid user and/or save it for
|
||||
later, for use in :meth:`~formtools.preview.FormPreview.done()`.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -138,12 +138,17 @@ class FormPreview(object):
|
|||
"""
|
||||
Given a validated form, performs any extra processing before displaying
|
||||
the preview page, and saves any extra data in context.
|
||||
|
||||
By default, this method is empty. It is called after the form is
|
||||
validated, but before the context is modified with hash information
|
||||
and rendered.
|
||||
"""
|
||||
pass
|
||||
|
||||
def security_hash(self, request, form):
|
||||
"""
|
||||
Calculates the security hash for the given HttpRequest and Form
|
||||
Calculates the security hash for the given
|
||||
:class:`~django.http.HttpRequest` and :class:`~django.forms.Form`
|
||||
instances.
|
||||
|
||||
Subclasses may want to take into account request-specific information,
|
||||
|
@ -152,15 +157,19 @@ class FormPreview(object):
|
|||
return form_hmac(form)
|
||||
|
||||
def failed_hash(self, request):
|
||||
"Returns an HttpResponse in the case of an invalid security hash."
|
||||
"""
|
||||
Returns an :class:`~django.http.HttpResponse` in the case of
|
||||
an invalid security hash.
|
||||
"""
|
||||
return self.preview_post(request)
|
||||
|
||||
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
||||
|
||||
def done(self, request, cleaned_data):
|
||||
"""
|
||||
Does something with the cleaned_data and returns an
|
||||
HttpResponseRedirect.
|
||||
Does something with the ``cleaned_data`` data and then needs to
|
||||
return an :class:`~django.http.HttpResponseRedirect`, e.g. to a
|
||||
success page.
|
||||
"""
|
||||
raise NotImplementedError('You must define a done() method on your '
|
||||
'%s subclass.' % self.__class__.__name__)
|
||||
|
|
Loading…
Reference in New Issue