Django

Code

Ticket #3218: form_wizard.txt

File form_wizard.txt, 3.2 kB (added by mdorn, 3 years ago)

Updated documentation, final.

Line 
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.