1 | ===========
|
---|
2 | Form Wizard
|
---|
3 | ===========
|
---|
4 |
|
---|
5 | **New in Django devleopment version.**
|
---|
6 |
|
---|
7 | The form wizard allows you to divide your forms into multiple pages,
|
---|
8 | maintaining form data in hidden fields until submission in the final step.
|
---|
9 |
|
---|
10 | Usage
|
---|
11 | =====
|
---|
12 |
|
---|
13 | Define the forms you will use in you wizard in a ``forms.py`` file for your
|
---|
14 | application::
|
---|
15 |
|
---|
16 | from django import newforms as forms
|
---|
17 |
|
---|
18 | class ContactForm(forms.Form):
|
---|
19 | subject = forms.CharField(max_length=100)
|
---|
20 | message = forms.CharField()
|
---|
21 | sender = forms.EmailField()
|
---|
22 | cc_myself = forms.BooleanField()
|
---|
23 |
|
---|
24 | class ContactFormPage2(forms.Form):
|
---|
25 | code = forms.CharField()
|
---|
26 |
|
---|
27 | .. warning:: Do not include ``FileField`` or ``ImageField`` in any form that
|
---|
28 | will not be displayed on the last page of your form wizard.
|
---|
29 |
|
---|
30 | In your application's ``views.py``, subclass a form wizard object. You'll
|
---|
31 | need to override the ``done`` method with your own form processing code.
|
---|
32 | In the example below, rather than perform any database operation, the method
|
---|
33 | simply returns a list of the (validated) data the user entered into the form
|
---|
34 | to be displayed by a template ``done.html``::
|
---|
35 |
|
---|
36 | from django.shortcuts import render_to_response
|
---|
37 | from django.contrib.formtools.wizard import Wizard
|
---|
38 |
|
---|
39 | class ContactWizard(Wizard):
|
---|
40 | def done(self, request, form_list):
|
---|
41 | return render_to_response('done.html',
|
---|
42 | {'form_data' : [ form.cleaned_data for form in form_list ] })
|
---|
43 |
|
---|
44 | Next, connect your new form wizard object to the path of your choosing in
|
---|
45 | ``urls.py``. The wizard takes a list of your form objects as arguments::
|
---|
46 |
|
---|
47 | from django.conf.urls.defaults import *
|
---|
48 | from mysite.testapp.forms import ContactForm, ContactFormPage2
|
---|
49 | from mysite.testapp.views import ContactWizard
|
---|
50 |
|
---|
51 | urlpatterns = patterns('',
|
---|
52 | (r'^contact/$', ContactWizard([ContactForm, ContactFormPage2])),
|
---|
53 | )
|
---|
54 |
|
---|
55 | Finally, you'll need to create a template named ``wizard.html`` in your
|
---|
56 | ``templates`` directory. That template will contain template code that will
|
---|
57 | display your form fields so that they can be processed properly by the form
|
---|
58 | wizard. For example::
|
---|
59 |
|
---|
60 | {% extends "base.html" %}
|
---|
61 | {% block content %}
|
---|
62 | <p>Step {{ current_step }} of {{ step_count }}</p>
|
---|
63 | <form action="." method="POST">
|
---|
64 | <table>
|
---|
65 | {{ form }}
|
---|
66 | </table>
|
---|
67 | <input type="hidden" name="{{ step_field }}" value="{{ step }}" />
|
---|
68 | <!-- include previous fields -->
|
---|
69 | {{ previous_fields }}
|
---|
70 | <input type="submit">
|
---|
71 | </form>
|
---|
72 | {% endblock %}
|
---|
73 |
|
---|
74 | The ``current_step`` and ``step_count`` variables can be displayed to notify
|
---|
75 | your users where they are in the process. Note also the presence of the
|
---|
76 | template variables ``step_fields``, ``step``, ``previous_fields``, which are
|
---|
77 | used for hidden form fields.
|
---|
78 |
|
---|
79 | Advanced Usage
|
---|
80 | ==============
|
---|
81 |
|
---|
82 | You may override the ``process_step`` method in your wizard class to, for
|
---|
83 | example, dynamically generate a ``form_list`` and/or add items to
|
---|
84 | ``self.extra_context`` based on the contents of previously submitted forms::
|
---|
85 |
|
---|
86 | def process_step(self, request, form, step):
|
---|
87 | if step == 0:
|
---|
88 | # do something for the second step in your form wizard
|
---|
89 | # based on data submitted from step 1
|
---|
90 |
|
---|
91 | The method is called every time a page is rendered, for all submitted steps.
|
---|