Ticket #10557: trac-10557.diff

File trac-10557.diff, 6.2 KB (added by steph, 5 years ago)

Patch with tests and docs.

  • django/contrib/formtools/tests/__init__.py

    diff --git a/django/contrib/formtools/tests/__init__.py b/django/contrib/formtools/tests/__init__.py
    index 9c7d46f..b194845 100644
    a b class WizardTests(TestCase): 
    360360                "wizard_step": "1"}
    361361        wizard(DummyRequest(POST=data))
    362362
     363    def test_prev_fields_as_hidden(self):
     364        """
     365        Previous fields should be available as hidden fields.
     366        """
     367        data = {"0-field": "test",
     368                "1-field": "test2",
     369                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
     370                "wizard_step": "1"}
     371
     372        previous_fields = '<input type="hidden" name="0-field" value="test" id="id_0-field" /><input type="hidden" name="hash_0" value="7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c" id="id_hash_0" /><input type="hidden" name="1-field" value="test2" id="id_1-field" /><input type="hidden" name="hash_1" value="d5b434e3934cc92fee4bd2964c4ebc06f81d362d" id="id_hash_1" />'
     373
     374        response = self.client.post('/wizard/', data)
     375        self.assertEquals(2, response.context['step0'])
     376        self.assertEquals(previous_fields, response.context['previous_fields'])
     377
     378    def test_prev_fields_as_list(self):
     379        """
     380        Previous fields should be available as hidden fields.
     381        """
     382        data = {"0-field": "test",
     383                "1-field": "test2",
     384                "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
     385                "wizard_step": "1"}
     386
     387        response = self.client.post('/wizard/', data)
     388        self.assertEquals(2, response.context['step0'])
     389
     390        the_fields = [(f.html_name, f.data if f.form.is_bound else f.form.initial.get(f.name, f.field.initial)) for f in response.context['previous_fields_list']]
     391
     392        self.assertEquals(the_fields, [('0-field', u'test'), ('hash_0', u'7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c'), ('1-field', u'test2'), ('hash_1', 'd5b434e3934cc92fee4bd2964c4ebc06f81d362d')])
     393
  • django/contrib/formtools/wizard.py

    diff --git a/django/contrib/formtools/wizard.py b/django/contrib/formtools/wizard.py
    index d382e29..7ae225f 100644
    a b import cPickle as pickle 
    99from django import forms
    1010from django.conf import settings
    1111from django.contrib.formtools.utils import security_hash, form_hmac
     12from django.forms.forms import BoundField
    1213from django.http import Http404
    1314from django.shortcuts import render_to_response
    1415from django.template.context import RequestContext
    class FormWizard(object): 
    145146        prev_fields = []
    146147        if old_data:
    147148            hidden = forms.HiddenInput()
    148             # Collect all data from previous steps and render it as HTML hidden fields.
     149            # Collect all data from previous steps
    149150            for i in range(step):
    150151                old_form = self.get_form(i, old_data)
    151152                hash_name = 'hash_%s' % i
    152                 prev_fields.extend([bf.as_hidden() for bf in old_form])
    153                 prev_fields.append(hidden.render(hash_name, old_data.get(hash_name, self.security_hash(request, old_form))))
    154         return self.render_template(request, form, ''.join(prev_fields), step, context)
     153                prev_fields.extend([bf for bf in old_form])
     154                hash_field = forms.Field(
     155                    initial=old_data.get(
     156                        hash_name,
     157                        self.security_hash(request, old_form)))
     158                hash_bf = BoundField(forms.Form(), hash_field, hash_name)
     159                prev_fields.append(hash_bf)
     160
     161        # render the previous fields as HTML hidden fields.
     162        html_prev_fields = ''.join([f.as_hidden() for f in prev_fields])
     163
     164        return self.render_template(request, form, html_prev_fields,
     165                                    prev_fields, step, context)
    155166
    156167    # METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
    157168
    class FormWizard(object): 
    223234        """
    224235        return 'forms/wizard.html'
    225236
    226     def render_template(self, request, form, previous_fields, step, context=None):
     237    def render_template(self, request, form, previous_fields,
     238                        previous_fields_list, step, context=None):
    227239        """
    228240        Renders the template for the given step, returning an HttpResponse object.
    229241
    class FormWizard(object): 
    243255                          hidden fields. Note that you'll need to run this
    244256                          through the "safe" template filter, to prevent
    245257                          auto-escaping, because it's raw HTML.
     258            previous_fields_list -- A list containing every previous data
     259                          field, plus hashes for completed forms, all in the
     260                          form of regular fields. Note that you'll need to
     261                          call :meth:`as_hidden` on each field to prevent
     262                          them from appearing in your forms.
    246263        """
    247264        context = context or {}
    248265        context.update(self.extra_context)
    class FormWizard(object): 
    252269            step=step + 1,
    253270            step_count=self.num_steps(),
    254271            form=form,
    255             previous_fields=previous_fields
     272            previous_fields=previous_fields,
     273            previous_fields_list=previous_fields_list
    256274        ), context_instance=RequestContext(request))
    257275
    258276    def process_step(self, request, form, step):
  • docs/ref/contrib/formtools/form-wizard.txt

    diff --git a/docs/ref/contrib/formtools/form-wizard.txt b/docs/ref/contrib/formtools/form-wizard.txt
    index 370fbdc..653e27e 100644
    a b This template expects the following context: 
    152152      plus hashes for completed forms, all in the form of hidden fields. Note
    153153      that you'll need to run this through the :tfilter:`safe` template filter,
    154154      to prevent auto-escaping, because it's raw HTML.
     155    ' ``previous_fields_list`` -- A list containing every previous data field,
     156      plus hashes for completed forms, all in the form of regular fields. Note
     157      that you'll need to call :meth:`as_hidden` on each field to prevent them
     158      from appearing in your forms.
    155159
    156160You can supply extra context to this template in two ways:
    157161
Back to Top