Ticket #10557: trac-10557.2.diff

File trac-10557.2.diff, 6.6 KB (added by steph, 13 years ago)

Better patch with argument inspection

  • 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..a1c6af2 100644
    a b stored on the server side.  
    55"""
    66
    77import cPickle as pickle
     8import inspect
    89
    910from django import forms
    1011from django.conf import settings
    1112from django.contrib.formtools.utils import security_hash, form_hmac
     13from django.forms.forms import BoundField
    1214from django.http import Http404
    1315from django.shortcuts import render_to_response
    1416from django.template.context import RequestContext
    class FormWizard(object):  
    145147        prev_fields = []
    146148        if old_data:
    147149            hidden = forms.HiddenInput()
    148             # Collect all data from previous steps and render it as HTML hidden fields.
     150            # Collect all data from previous steps
    149151            for i in range(step):
    150152                old_form = self.get_form(i, old_data)
    151153                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)
     154                prev_fields.extend([bf for bf in old_form])
     155                hash_field = forms.Field(
     156                    initial=old_data.get(
     157                        hash_name,
     158                        self.security_hash(request, old_form)))
     159                hash_bf = BoundField(forms.Form(), hash_field, hash_name)
     160                prev_fields.append(hash_bf)
     161
     162        # render the previous fields as HTML hidden fields.
     163        html_prev_fields = ''.join([f.as_hidden() for f in prev_fields])
     164
     165        method_args = inspect.getargspec(self.render_template).args
     166        if 'previous_fields_list' in method_args:
     167            return self.render_template(request, form, html_prev_fields,
     168                                        step, context,
     169                                        previous_fields_list=prev_fields)
     170        else:
     171            return self.render_template(request, form, html_prev_fields,
     172                                        step, context)
    155173
    156174    # METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
    157175
    class FormWizard(object):  
    223241        """
    224242        return 'forms/wizard.html'
    225243
    226     def render_template(self, request, form, previous_fields, step, context=None):
     244    def render_template(self, request, form, previous_fields,
     245                        step, context=None, previous_fields_list=None):
    227246        """
    228247        Renders the template for the given step, returning an HttpResponse object.
    229248
    class FormWizard(object):  
    243262                          hidden fields. Note that you'll need to run this
    244263                          through the "safe" template filter, to prevent
    245264                          auto-escaping, because it's raw HTML.
     265            previous_fields_list -- A list containing every previous data
     266                          field, plus hashes for completed forms, all in the
     267                          form of regular fields. Note that you'll need to
     268                          call :meth:`as_hidden` on each field to prevent
     269                          them from appearing in your forms.
    246270        """
    247271        context = context or {}
    248272        context.update(self.extra_context)
    class FormWizard(object):  
    252276            step=step + 1,
    253277            step_count=self.num_steps(),
    254278            form=form,
    255             previous_fields=previous_fields
     279            previous_fields=previous_fields,
     280            previous_fields_list=previous_fields_list
    256281        ), context_instance=RequestContext(request))
    257282
    258283    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