diff --git a/pyramid_deform/__init__.py b/pyramid_deform/__init__.py index 675ea02..7a65ea9 100644 --- a/pyramid_deform/__init__.py +++ b/pyramid_deform/__init__.py @@ -73,9 +73,26 @@ def get_bind_data(self): """ return {'request': self.request} + def prepare_form(self): + """ + Prepares the form object according to the provided options. + + This method, in addition to instantiating an instance of the + given :attr:``form_class``, will process the form by calling + :meth:`before`. Returns an instance of the :attr:`form_class`. + """ + use_ajax = getattr(self, 'use_ajax', False) + ajax_options = getattr(self, 'ajax_options', '{}') + self.schema = self.schema.bind(**self.get_bind_data()) + form = self.form_class(self.schema, buttons=self.buttons, + use_ajax=use_ajax, ajax_options=ajax_options, + **dict(self.form_options)) + self.before(form) + return form + def __call__(self): """ - Prepares and render the form according to provided options. + Prepares and renders the form according to provided options. Upon receiving a ``POST`` request, this method will validate the request against the form instance. After validation, @@ -90,13 +107,7 @@ def __call__(self): Returns a ``dict`` structure suitable for provision tog the given view. By default, this is the page template specified """ - use_ajax = getattr(self, 'use_ajax', False) - ajax_options = getattr(self, 'ajax_options', '{}') - self.schema = self.schema.bind(**self.get_bind_data()) - form = self.form_class(self.schema, buttons=self.buttons, - use_ajax=use_ajax, ajax_options=ajax_options, - **dict(self.form_options)) - self.before(form) + form = self.prepare_form() reqts = form.get_widget_resources() result = None @@ -130,8 +141,8 @@ def before(self, form): By default, this method does nothing. Override this method in your dervived class to modify the ``form``. Your function will be executed immediately after instansiating the form - instance in :meth:`__call__` (thus before obtaining widget resources, - considering buttons, or rendering). + instance in :meth:`prepare_form` (thus before obtaining widget + resources, considering buttons, or rendering during :meth:`__call__`). """ pass diff --git a/pyramid_deform/tests.py b/pyramid_deform/tests.py index a1a79c9..974b2a2 100644 --- a/pyramid_deform/tests.py +++ b/pyramid_deform/tests.py @@ -142,6 +142,23 @@ def check_form(self, form): for key, value in dict(form_options).items(): self.assertEqual(getattr(form, key), value) + def test_prepare_form(self): + schema = DummySchema() + request = DummyRequest() + inst = self._makeOne(request) + inst.schema = schema + inst.form_class = DummyForm + + def manipulate_form(self, form): + form.custom_attr = 'custom-attr' + + inst.before = types.MethodType(manipulate_form, inst) + form = inst.prepare_form() + + #Form should be correct type and customised according to options + self.assertTrue(isinstance(form, DummyForm)) + self.assertEqual(form.custom_attr, 'custom-attr') + class TestFormWizardView(unittest.TestCase): def _makeOne(self, wizard): from pyramid_deform import FormWizardView