Loading django/contrib/formtools/tests/wizard/forms.py +29 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,12 @@ class TestWizard(WizardView): kwargs['test'] = True return kwargs class TestWizardWithInitAttrs(TestWizard): form_list = [Step1, Step2] condition_dict = {'step2': True} initial_dict = {'start': {'name': 'value1'}} instance_dict = {'start': User()} class FormTests(TestCase): def test_form_init(self): testform = TestWizard.get_initkwargs([Step1, Step2]) Loading @@ -91,6 +97,9 @@ class FormTests(TestCase): self.assertEqual( testform['form_list'], {'0': Step1, '1': Step2, 'finish': Step3}) testform = TestWizardWithInitAttrs.get_initkwargs() self.assertEqual(testform['form_list'], {'0': Step1, '1': Step2}) def test_first_step(self): request = get_request() Loading Loading @@ -132,6 +141,11 @@ class FormTests(TestCase): response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step3') testform = TestWizardWithInitAttrs.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)]) response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step2') def test_form_kwargs(self): request = get_request() Loading Loading @@ -162,6 +176,13 @@ class FormTests(TestCase): self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) self.assertEqual(instance.get_form_initial('step2'), {}) testform = TestWizardWithInitAttrs.as_view( [('start', Step1), ('step2', Step2)]) response, instance = testform(request) self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) self.assertEqual(instance.get_form_initial('step2'), {}) def test_form_instance(self): request = get_request() the_instance = TestModel() Loading @@ -176,6 +197,14 @@ class FormTests(TestCase): instance.get_form_instance('non_exist_instance'), None) testform = TestWizardWithInitAttrs.as_view( [('start', TestModelForm), ('step2', Step2)]) response, instance = testform(request) self.assertEqual( instance.get_form_instance('start'), TestWizardWithInitAttrs.instance_dict['start']) def test_formset_instance(self): request = get_request() the_instance1, created = TestModel.objects.get_or_create( Loading django/contrib/formtools/wizard/views.py +18 −10 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ class WizardView(TemplateView): return super(WizardView, cls).as_view(**initkwargs) @classmethod def get_initkwargs(cls, form_list, initial_dict=None, def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=None, condition_dict=None, *args, **kwargs): """ Creates a dict with all needed parameters for the form wizard instances. Loading @@ -144,12 +144,20 @@ class WizardView(TemplateView): will be called with the wizardview instance as the only argument. If the return value is true, the step's form will be used. """ kwargs.update({ 'initial_dict': initial_dict or {}, 'instance_dict': instance_dict or {}, 'condition_dict': condition_dict or {}, 'initial_dict': initial_dict or kwargs.pop('initial_dict', getattr(cls, 'initial_dict', None)) or {}, 'instance_dict': instance_dict or kwargs.pop('instance_dict', getattr(cls, 'instance_dict', None)) or {}, 'condition_dict': condition_dict or kwargs.pop('condition_dict', getattr(cls, 'condition_dict', None)) or {} }) init_form_list = SortedDict() form_list = form_list or kwargs.pop('form_list', getattr(cls, 'form_list', None)) or [] computed_form_list = SortedDict() assert len(form_list) > 0, 'at least one form is needed' Loading @@ -158,13 +166,13 @@ class WizardView(TemplateView): if isinstance(form, (list, tuple)): # if the element is a tuple, add the tuple to the new created # sorted dictionary. init_form_list[six.text_type(form[0])] = form[1] computed_form_list[six.text_type(form[0])] = form[1] else: # if not, add the form with a zero based counter as unicode init_form_list[six.text_type(i)] = form computed_form_list[six.text_type(i)] = form # walk through the new created list of forms for form in six.itervalues(init_form_list): for form in six.itervalues(computed_form_list): if issubclass(form, formsets.BaseFormSet): # if the element is based on BaseFormSet (FormSet/ModelFormSet) # we need to override the form variable. Loading @@ -179,7 +187,7 @@ class WizardView(TemplateView): "wizard view in order to handle file uploads.") # build the kwargs for the wizardview instances kwargs['form_list'] = init_form_list kwargs['form_list'] = computed_form_list return kwargs def get_prefix(self, *args, **kwargs): Loading docs/ref/contrib/formtools/form-wizard.txt +20 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,13 @@ wizard's ``as_view()`` method takes a list of your (r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])), ) .. versionchanged:: 1.6 You can also pass the form list as a class attribute named ``form_list``. class ContactWizard(WizardView): form_list = [ContactForm1, ContactForm2] .. _wizard-template-for-each-form: Using a different template for each form Loading Loading @@ -295,6 +302,14 @@ The ``urls.py`` file would contain something like:: (r'^checkout/$', OrderWizard.as_view(FORMS, condition_dict={'cc': pay_by_credit_card})), ) .. versionchanged:: 1.6 The ``condiction_dict`` can be passed as attribute for the ``as_view()`` method or as a class attribute named ``condition_dict``. class OrderWizard(WizardView): condition_dict = {'cc': pay_by_credit_card} Note that the ``OrderWizard`` object is initialized with a list of pairs. The first element in the pair is a string that corresponds to the name of the step and the second is the form class. Loading Loading @@ -550,6 +565,11 @@ Providing initial data for the forms The ``initial_dict`` can also take a list of dictionaries for a specific step if the step is a ``FormSet``. .. versionchanged:: 1.6 The ``initial_dict`` can also be added as a class attribute named ``initial_dict`` to avoid having the initial data in the ``urls.py``. .. _wizard-files: Handling files Loading Loading
django/contrib/formtools/tests/wizard/forms.py +29 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,12 @@ class TestWizard(WizardView): kwargs['test'] = True return kwargs class TestWizardWithInitAttrs(TestWizard): form_list = [Step1, Step2] condition_dict = {'step2': True} initial_dict = {'start': {'name': 'value1'}} instance_dict = {'start': User()} class FormTests(TestCase): def test_form_init(self): testform = TestWizard.get_initkwargs([Step1, Step2]) Loading @@ -91,6 +97,9 @@ class FormTests(TestCase): self.assertEqual( testform['form_list'], {'0': Step1, '1': Step2, 'finish': Step3}) testform = TestWizardWithInitAttrs.get_initkwargs() self.assertEqual(testform['form_list'], {'0': Step1, '1': Step2}) def test_first_step(self): request = get_request() Loading Loading @@ -132,6 +141,11 @@ class FormTests(TestCase): response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step3') testform = TestWizardWithInitAttrs.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)]) response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step2') def test_form_kwargs(self): request = get_request() Loading Loading @@ -162,6 +176,13 @@ class FormTests(TestCase): self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) self.assertEqual(instance.get_form_initial('step2'), {}) testform = TestWizardWithInitAttrs.as_view( [('start', Step1), ('step2', Step2)]) response, instance = testform(request) self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) self.assertEqual(instance.get_form_initial('step2'), {}) def test_form_instance(self): request = get_request() the_instance = TestModel() Loading @@ -176,6 +197,14 @@ class FormTests(TestCase): instance.get_form_instance('non_exist_instance'), None) testform = TestWizardWithInitAttrs.as_view( [('start', TestModelForm), ('step2', Step2)]) response, instance = testform(request) self.assertEqual( instance.get_form_instance('start'), TestWizardWithInitAttrs.instance_dict['start']) def test_formset_instance(self): request = get_request() the_instance1, created = TestModel.objects.get_or_create( Loading
django/contrib/formtools/wizard/views.py +18 −10 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ class WizardView(TemplateView): return super(WizardView, cls).as_view(**initkwargs) @classmethod def get_initkwargs(cls, form_list, initial_dict=None, def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=None, condition_dict=None, *args, **kwargs): """ Creates a dict with all needed parameters for the form wizard instances. Loading @@ -144,12 +144,20 @@ class WizardView(TemplateView): will be called with the wizardview instance as the only argument. If the return value is true, the step's form will be used. """ kwargs.update({ 'initial_dict': initial_dict or {}, 'instance_dict': instance_dict or {}, 'condition_dict': condition_dict or {}, 'initial_dict': initial_dict or kwargs.pop('initial_dict', getattr(cls, 'initial_dict', None)) or {}, 'instance_dict': instance_dict or kwargs.pop('instance_dict', getattr(cls, 'instance_dict', None)) or {}, 'condition_dict': condition_dict or kwargs.pop('condition_dict', getattr(cls, 'condition_dict', None)) or {} }) init_form_list = SortedDict() form_list = form_list or kwargs.pop('form_list', getattr(cls, 'form_list', None)) or [] computed_form_list = SortedDict() assert len(form_list) > 0, 'at least one form is needed' Loading @@ -158,13 +166,13 @@ class WizardView(TemplateView): if isinstance(form, (list, tuple)): # if the element is a tuple, add the tuple to the new created # sorted dictionary. init_form_list[six.text_type(form[0])] = form[1] computed_form_list[six.text_type(form[0])] = form[1] else: # if not, add the form with a zero based counter as unicode init_form_list[six.text_type(i)] = form computed_form_list[six.text_type(i)] = form # walk through the new created list of forms for form in six.itervalues(init_form_list): for form in six.itervalues(computed_form_list): if issubclass(form, formsets.BaseFormSet): # if the element is based on BaseFormSet (FormSet/ModelFormSet) # we need to override the form variable. Loading @@ -179,7 +187,7 @@ class WizardView(TemplateView): "wizard view in order to handle file uploads.") # build the kwargs for the wizardview instances kwargs['form_list'] = init_form_list kwargs['form_list'] = computed_form_list return kwargs def get_prefix(self, *args, **kwargs): Loading
docs/ref/contrib/formtools/form-wizard.txt +20 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,13 @@ wizard's ``as_view()`` method takes a list of your (r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])), ) .. versionchanged:: 1.6 You can also pass the form list as a class attribute named ``form_list``. class ContactWizard(WizardView): form_list = [ContactForm1, ContactForm2] .. _wizard-template-for-each-form: Using a different template for each form Loading Loading @@ -295,6 +302,14 @@ The ``urls.py`` file would contain something like:: (r'^checkout/$', OrderWizard.as_view(FORMS, condition_dict={'cc': pay_by_credit_card})), ) .. versionchanged:: 1.6 The ``condiction_dict`` can be passed as attribute for the ``as_view()`` method or as a class attribute named ``condition_dict``. class OrderWizard(WizardView): condition_dict = {'cc': pay_by_credit_card} Note that the ``OrderWizard`` object is initialized with a list of pairs. The first element in the pair is a string that corresponds to the name of the step and the second is the form class. Loading Loading @@ -550,6 +565,11 @@ Providing initial data for the forms The ``initial_dict`` can also take a list of dictionaries for a specific step if the step is a ``FormSet``. .. versionchanged:: 1.6 The ``initial_dict`` can also be added as a class attribute named ``initial_dict`` to avoid having the initial data in the ``urls.py``. .. _wizard-files: Handling files Loading