Browse Source

Fixed #21994 -- Added form_dict argument to calls of WizardView.done()

Added an additional keyword argument ``form_dict`` to calls of
WizardView.done() implementations which allows easier access to validated
forms by their step name.
Julian Wachholz 11 years ago
parent
commit
9a4ee8ddb8

+ 1 - 0
django/contrib/formtools/tests/wizard/namedwizardtests/forms.py

@@ -39,6 +39,7 @@ class ContactWizard(NamedUrlWizardView):
     def done(self, form_list, **kwargs):
         c = Context({
             'form_list': [x.cleaned_data for x in form_list],
+            'form_dict': kwargs.get('form_dict'),
             'all_cleaned_data': self.get_all_cleaned_data()
         })
 

+ 5 - 0
django/contrib/formtools/tests/wizard/namedwizardtests/tests.py

@@ -219,6 +219,11 @@ class NamedWizardTests(object):
                  {'random_crap': 'blah blah'}
              ]})
 
+        form_dict = response.context['form_dict']
+        self.assertIn('form1', form_dict.keys())
+        self.assertIn('form2', form_dict.keys())
+        self.assertEqual(form_dict['form1'].cleaned_data, response.context['form_list'][0])
+
     def test_manipulated_data(self):
         response = self.client.get(
             reverse(self.wizard_urlname, kwargs={'step': 'form1'}))

+ 3 - 3
django/contrib/formtools/wizard/views.py

@@ -335,7 +335,7 @@ class WizardView(TemplateView):
         validate, `render_revalidation_failure` should get called.
         If everything is fine call `done`.
         """
-        final_form_list = []
+        final_forms = OrderedDict()
         # walk through the form list and try to validate the data again.
         for form_key in self.get_form_list():
             form_obj = self.get_form(step=form_key,
@@ -343,12 +343,12 @@ class WizardView(TemplateView):
                 files=self.storage.get_step_files(form_key))
             if not form_obj.is_valid():
                 return self.render_revalidation_failure(form_key, form_obj, **kwargs)
-            final_form_list.append(form_obj)
+            final_forms[form_key] = form_obj
 
         # render the done view and reset the wizard before returning the
         # response. This is needed to prevent from rendering done with the
         # same data twice.
-        done_response = self.done(final_form_list, **kwargs)
+        done_response = self.done(final_forms.values(), form_dict=final_forms, **kwargs)
         self.storage.reset()
         return done_response
 

+ 18 - 3
docs/ref/contrib/formtools/form-wizard.txt

@@ -114,11 +114,11 @@ anywhere in your codebase, but convention is to put it in :file:`views.py`.
 The only requirement on this subclass is that it implement a
 :meth:`~WizardView.done()` method.
 
-.. method:: WizardView.done(form_list)
+.. method:: WizardView.done(form_list, form_dict, **kwargs)
 
     This method specifies what should happen when the data for *every* form is
-    submitted and validated. This method is passed a list of validated
-    :class:`~django.forms.Form` instances.
+    submitted and validated. This method is passed a list and dictionary of
+    validated :class:`~django.forms.Form` instances.
 
     In this simplistic example, rather than performing any database operation,
     the method simply renders a template of the validated data::
@@ -144,6 +144,21 @@ The only requirement on this subclass is that it implement a
                 do_something_with_the_form_data(form_list)
                 return HttpResponseRedirect('/page-to-redirect-to-when-done/')
 
+    In addition to ``form_list``, the :meth:`~WizardView.done` method
+    is passed a ``form_dict``, which allows you to access the wizard's
+    forms based on their step names. This is especially useful when using
+    :class:`NamedUrlWizardView`, for example::
+
+        def done(self, form_list, form_dict, **kwargs):
+            user = form_dict['user'].save()
+            credit_card = form_dict['credit_card'].save()
+            # ...
+
+    .. versionchanged:: 1.7
+
+        Previously, the ``form_dict`` argument wasn't passed to the
+        ``done`` method.
+
 See the section :ref:`Advanced WizardView methods <wizardview-advanced-methods>`
 below to learn about more :class:`WizardView` hooks.
 

+ 7 - 0
docs/releases/1.7.txt

@@ -310,6 +310,13 @@ Minor features
   ``html_email_template_name`` parameter used to send a multipart HTML email
   for password resets.
 
+:mod:`django.contrib.formtools`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Calls to :meth:`WizardView.done()
+  <django.contrib.formtools.wizard.views.WizardView.done>` now include a
+  ``form_dict`` to allow easier access to forms by their step name.
+
 :mod:`django.contrib.gis`
 ^^^^^^^^^^^^^^^^^^^^^^^^^^