summaryrefslogtreecommitdiff
path: root/parts/django/docs/ref/contrib/formtools
diff options
context:
space:
mode:
Diffstat (limited to 'parts/django/docs/ref/contrib/formtools')
-rw-r--r--parts/django/docs/ref/contrib/formtools/form-preview.txt121
-rw-r--r--parts/django/docs/ref/contrib/formtools/form-wizard.txt312
-rw-r--r--parts/django/docs/ref/contrib/formtools/index.txt10
3 files changed, 0 insertions, 443 deletions
diff --git a/parts/django/docs/ref/contrib/formtools/form-preview.txt b/parts/django/docs/ref/contrib/formtools/form-preview.txt
deleted file mode 100644
index a2cbea7..0000000
--- a/parts/django/docs/ref/contrib/formtools/form-preview.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-============
-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.
-
-Advanced ``FormPreview`` methods
-================================
-
-.. versionadded:: 1.2
-
-.. method:: FormPreview.process_preview
-
- 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.
diff --git a/parts/django/docs/ref/contrib/formtools/form-wizard.txt b/parts/django/docs/ref/contrib/formtools/form-wizard.txt
deleted file mode 100644
index 390d575..0000000
--- a/parts/django/docs/ref/contrib/formtools/form-wizard.txt
+++ /dev/null
@@ -1,312 +0,0 @@
-===========
-Form wizard
-===========
-
-.. module:: django.contrib.formtools.wizard
- :synopsis: Splits forms across multiple Web pages.
-
-.. versionadded:: 1.0
-
-Django comes with an optional "form wizard" application that splits
-:doc:`forms </topics/forms/index>` across multiple Web pages. It maintains
-state in hashed HTML :samp:`<input type="hidden">` fields, and the data isn't
-processed server-side until the final form is submitted.
-
-You might want to use this if you have a lengthy form that would be too
-unwieldy for display on a single page. The first page might ask the user for
-core information, the second page might ask for less important information,
-etc.
-
-The term "wizard," in this context, is `explained on Wikipedia`_.
-
-.. _explained on Wikipedia: http://en.wikipedia.org/wiki/Wizard_%28software%29
-.. _forms: ../forms/
-
-How it works
-============
-
-Here's the basic workflow for how a user would use a wizard:
-
- 1. The user visits the first page of the wizard, fills in the form and
- submits it.
- 2. The server validates the data. If it's invalid, the form is displayed
- again, with error messages. If it's valid, the server calculates a
- secure hash of the data and presents the user with the next form,
- saving the validated data and hash in :samp:`<input type="hidden">`
- fields.
- 3. Step 1 and 2 repeat, for every subsequent form in the wizard.
- 4. Once the user has submitted all the forms and all the data has been
- validated, the wizard processes the data -- saving it to the database,
- sending an e-mail, or whatever the application needs to do.
-
-Usage
-=====
-
-This application handles as much machinery for you as possible. Generally, you
-just have to do these things:
-
- 1. Define a number of :class:`~django.forms.Form` classes -- one per wizard
- page.
-
- 2. Create a :class:`FormWizard` class that specifies what to do once all of
- your forms have been submitted and validated. This also lets you
- override some of the wizard's behavior.
-
- 3. Create some templates that render the forms. You can define a single,
- generic template to handle every one of the forms, or you can define a
- specific template for each form.
-
- 4. Point your URLconf at your :class:`FormWizard` class.
-
-Defining ``Form`` classes
-=========================
-
-The first step in creating a form wizard is to create the
-:class:`~django.forms.Form` classes. These should be standard
-:class:`django.forms.Form` classes, covered in the :doc:`forms documentation
-</topics/forms/index>`. These classes can live anywhere in your codebase, but
-convention is to put them in a file called :file:`forms.py` in your
-application.
-
-For example, let's write a "contact form" wizard, where the first page's form
-collects the sender's e-mail address and subject, and the second page collects
-the message itself. Here's what the :file:`forms.py` might look like::
-
- from django import forms
-
- class ContactForm1(forms.Form):
- subject = forms.CharField(max_length=100)
- sender = forms.EmailField()
-
- class ContactForm2(forms.Form):
- message = forms.CharField(widget=forms.Textarea)
-
-**Important limitation:** Because the wizard uses HTML hidden fields to store
-data between pages, you may not include a :class:`~django.forms.FileField`
-in any form except the last one.
-
-Creating a ``FormWizard`` class
-===============================
-
-The next step is to create a
-:class:`django.contrib.formtools.wizard.FormWizard` subclass. As with your
-:class:`~django.forms.Form` classes, this :class:`FormWizard` class can live
-anywhere in your codebase, but convention is to put it in :file:`forms.py`.
-
-The only requirement on this subclass is that it implement a
-:meth:`~FormWizard.done()` method.
-
-.. method:: FormWizard.done
-
- This method specifies what should happen when the data for *every* form is
- submitted and validated. This method is passed two arguments:
-
- * ``request`` -- an :class:`~django.http.HttpRequest` object
- * ``form_list`` -- a list of :class:`~django.forms.Form` classes
-
-In this simplistic example, rather than perform any database operation, the
-method simply renders a template of the validated data::
-
- from django.shortcuts import render_to_response
- from django.contrib.formtools.wizard import FormWizard
-
- class ContactWizard(FormWizard):
- def done(self, request, form_list):
- return render_to_response('done.html', {
- 'form_data': [form.cleaned_data for form in form_list],
- })
-
-Note that this method will be called via ``POST``, so it really ought to be a
-good Web citizen and redirect after processing the data. Here's another
-example::
-
- from django.http import HttpResponseRedirect
- from django.contrib.formtools.wizard import FormWizard
-
- class ContactWizard(FormWizard):
- def done(self, request, form_list):
- do_something_with_the_form_data(form_list)
- return HttpResponseRedirect('/page-to-redirect-to-when-done/')
-
-See the section `Advanced FormWizard methods`_ below to learn about more
-:class:`FormWizard` hooks.
-
-Creating templates for the forms
-================================
-
-Next, you'll need to create a template that renders the wizard's forms. By
-default, every form uses a template called :file:`forms/wizard.html`. (You can
-change this template name by overriding :meth:`~FormWizard.get_template()`,
-which is documented below. This hook also allows you to use a different
-template for each form.)
-
-This template expects the following context:
-
- * ``step_field`` -- The name of the hidden field containing the step.
- * ``step0`` -- The current step (zero-based).
- * ``step`` -- The current step (one-based).
- * ``step_count`` -- The total number of steps.
- * ``form`` -- The :class:`~django.forms.Form` instance for the current step
- (either empty or with errors).
- * ``previous_fields`` -- A string representing every previous data field,
- plus hashes for completed forms, all in the form of hidden fields. Note
- that you'll need to run this through the :tfilter:`safe` template filter,
- to prevent auto-escaping, because it's raw HTML.
-
-You can supply extra context to this template in two ways:
-
- * Set the :attr:`~FormWizard.extra_context` attribute on your
- :class:`FormWizard` subclass to a dictionary.
-
- * Pass a dictionary as a parameter named ``extra_context`` to your wizard's
- URL pattern in your URLconf. See :ref:`hooking-wizard-into-urlconf`.
-
-Here's a full example template:
-
-.. code-block:: html+django
-
- {% extends "base.html" %}
-
- {% block content %}
- <p>Step {{ step }} of {{ step_count }}</p>
- <form action="." method="post">{% csrf_token %}
- <table>
- {{ form }}
- </table>
- <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
- {{ previous_fields|safe }}
- <input type="submit">
- </form>
- {% endblock %}
-
-Note that ``previous_fields``, ``step_field`` and ``step0`` are all required
-for the wizard to work properly.
-
-.. _hooking-wizard-into-urlconf:
-
-Hooking the wizard into a URLconf
-=================================
-
-Finally, we need to specify which forms to use in the wizard, and then
-deploy the new :class:`FormWizard` object a URL in ``urls.py``. The
-wizard takes a list of your :class:`~django.forms.Form` objects as
-arguments when you instantiate the Wizard::
-
- from django.conf.urls.defaults import *
- from testapp.forms import ContactForm1, ContactForm2, ContactWizard
-
- urlpatterns = patterns('',
- (r'^contact/$', ContactWizard([ContactForm1, ContactForm2])),
- )
-
-Advanced ``FormWizard`` methods
-===============================
-
-.. class:: FormWizard
-
- Aside from the :meth:`~done()` method, :class:`FormWizard` offers a few
- advanced method hooks that let you customize how your wizard works.
-
- Some of these methods take an argument ``step``, which is a zero-based
- counter representing the current step of the wizard. (E.g., the first form
- is ``0`` and the second form is ``1``.)
-
-.. method:: FormWizard.prefix_for_step
-
- Given the step, returns a form prefix to use. By default, this simply uses
- the step itself. For more, see the :ref:`form prefix documentation
- <form-prefix>`.
-
- Default implementation::
-
- def prefix_for_step(self, step):
- return str(step)
-
-.. method:: FormWizard.render_hash_failure
-
- Renders a template if the hash check fails. It's rare that you'd need to
- override this.
-
- Default implementation::
-
- def render_hash_failure(self, request, step):
- return self.render(self.get_form(step), request, step,
- context={'wizard_error':
- 'We apologize, but your form has expired. Please'
- ' continue filling out the form from this page.'})
-
-.. method:: FormWizard.security_hash
-
- Calculates the security hash for the given request object and
- :class:`~django.forms.Form` instance.
-
- By default, this uses an MD5 hash of the form data and your
- :setting:`SECRET_KEY` setting. It's rare that somebody would need to
- override this.
-
- Example::
-
- def security_hash(self, request, form):
- return my_hash_function(request, form)
-
-.. method:: FormWizard.parse_params
-
- A hook for saving state from the request object and ``args`` / ``kwargs``
- that were captured from the URL by your URLconf.
-
- By default, this does nothing.
-
- Example::
-
- def parse_params(self, request, *args, **kwargs):
- self.my_state = args[0]
-
-.. method:: FormWizard.get_template
-
- Returns the name of the template that should be used for the given step.
-
- By default, this returns :file:`'forms/wizard.html'`, regardless of step.
-
- Example::
-
- def get_template(self, step):
- return 'myapp/wizard_%s.html' % step
-
- If :meth:`~FormWizard.get_template` returns a list of strings, then the
- wizard will use the template system's
- :func:`~django.template.loader.select_template` function.
- This means the system will use the first template that exists on the
- filesystem. For example::
-
- def get_template(self, step):
- return ['myapp/wizard_%s.html' % step, 'myapp/wizard.html']
-
-.. method:: FormWizard.render_template
-
- Renders the template for the given step, returning an
- :class:`~django.http.HttpResponse` object.
-
- Override this method if you want to add a custom context, return a
- different MIME type, etc. If you only need to override the template name,
- use :meth:`~FormWizard.get_template` instead.
-
- The template will be rendered with the context documented in the
- "Creating templates for the forms" section above.
-
-.. method:: FormWizard.process_step
-
- Hook for modifying the wizard's internal state, given a fully validated
- :class:`~django.forms.Form` object. The Form is guaranteed to have clean,
- valid data.
-
- This method should *not* modify any of that data. Rather, it might want to
- set ``self.extra_context`` or dynamically alter ``self.form_list``, based
- on previously submitted forms.
-
- Note that this method is called every time a page is rendered for *all*
- submitted steps.
-
- The function signature::
-
- def process_step(self, request, form, step):
- # ...
diff --git a/parts/django/docs/ref/contrib/formtools/index.txt b/parts/django/docs/ref/contrib/formtools/index.txt
deleted file mode 100644
index f364706..0000000
--- a/parts/django/docs/ref/contrib/formtools/index.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-django.contrib.formtools
-========================
-
-A set of high-level abstractions for Django forms (:mod:`django.forms`).
-
-.. toctree::
- :maxdepth: 1
-
- form-preview
- form-wizard