diff --git a/.gitignore b/.gitignore index 962e3ab45..22e309a18 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.pyo .*.swp .DS_Store +.idea/* # Extra Files MANIFEST diff --git a/tests/form.py b/tests/form.py index d7204b000..6fb14d170 100644 --- a/tests/form.py +++ b/tests/form.py @@ -10,6 +10,11 @@ class BaseFormTest(TestCase): + def strip_ws(self, s): + if isinstance(s, basestring): + s = s.strip() + return s + def get_form(self, **kwargs): def validate_test(form, field): if field.data != 'foobar': @@ -81,6 +86,17 @@ def test_formdata_wrapper_error(self): form = self.get_form() self.assertRaises(TypeError, form.process, []) + def test_form_filter(self): + form = self.get_form(form_filter=self.strip_ws) + form.process(test=' foo ') + self.assertEqual(form.data, {'test': 'foo'}) + + def test_form_filter_field_add(self): + form = self.get_form(form_filter=self.strip_ws) + form['test2'] = TextField() + form.process(test=' foo ', test2=' gappy text ') + self.assertEqual(form.data, {'test': 'foo', 'test2': 'gappy text'}) + class FormMetaTest(TestCase): def test_monkeypatch(self): diff --git a/wtforms/form.py b/wtforms/form.py index 9871ce7d7..2ca3fb1c6 100644 --- a/wtforms/form.py +++ b/wtforms/form.py @@ -19,7 +19,7 @@ class BaseForm(object): validation, and data and error proxying. """ - def __init__(self, fields, prefix='', meta=DefaultMeta()): + def __init__(self, fields, prefix='', meta=DefaultMeta(), form_filter=None): """ :param fields: A dict or sequence of 2-tuples of partially-constructed fields. @@ -37,10 +37,14 @@ def __init__(self, fields, prefix='', meta=DefaultMeta()): self._prefix = prefix self._errors = None self._fields = OrderedDict() + self.form_filter = form_filter if hasattr(fields, 'items'): fields = fields.items() + for field in fields: + self._apply_form_filter(field[1].kwargs) + translations = self._get_translations() extra_fields = [] if meta.csrf: @@ -66,12 +70,20 @@ def __getitem__(self, name): def __setitem__(self, name, value): """ Bind a field to this form. """ + value.kwargs = self._apply_form_filter(value.kwargs) self._fields[name] = value.bind(form=self, name=name, prefix=self._prefix) def __delitem__(self, name): """ Remove a field from this form. """ del self._fields[name] + def _apply_form_filter(self, field_kwargs): + if self.form_filter and hasattr(self.form_filter, '__call__'): + if 'filters' not in field_kwargs: + field_kwargs['filters'] = [] + field_kwargs['filters'].append(self.form_filter) + return field_kwargs + def _get_translations(self): """ .. deprecated:: 2.0 @@ -241,7 +253,8 @@ class Form(with_metaclass(FormMeta, BaseForm)): """ Meta = DefaultMeta - def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs): + def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, + form_filter=None, **kwargs): """ :param formdata: Used to pass data coming from the enduser, usually `request.POST` or @@ -269,7 +282,8 @@ def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **k meta_obj = self._wtforms_meta() if meta is not None and isinstance(meta, dict): meta_obj.update_values(meta) - super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix) + super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix, + form_filter=form_filter) for name, field in iteritems(self._fields): # Set all the fields to attributes so that they obscure the class