from django import forms def autostrip(cls): fields = [(key, value) for key, value in cls.base_fields.iteritems() if isinstance(value, forms.CharField)] for field_name, field_object in fields: def get_clean_func(original_clean): return lambda value: original_clean(value and value.strip()) clean_func = get_clean_func(getattr(field_object, 'clean')) setattr(field_object, 'clean', clean_func) return cls __test__ = {'USAGE': """ # Few lines to configure the test environment... >>> from django.conf import settings >>> settings.configure() # Lets define a form that will be used for the test. Note last line of this block, thats how # we apply ``autostrip`` decorator. >>> class PersonForm(forms.Form): ... name = forms.CharField(min_length=2, max_length=10) ... email = forms.EmailField() ... ... def clean_name(self): ... return self.cleaned_data['name'].capitalize() >>> PersonForm = autostrip(PersonForm) # Lets see how autostrip works against data with leading and trailing whitespace. # Autostrip is performed on ``CharField``s and all its descendants such as ``EmailField``, # ``URLField``, ``RegexField``, etc. >>> form = PersonForm({'name': ' Victor ', 'email': ' secret@example.ru '}) >>> form.is_valid() True >>> form.cleaned_data {'name': u'Victor', 'email': u'secret@example.ru'} # ``clean_*`` methods works after stripping, so the letter and not the space is capitalized: >>> form = PersonForm({'name': ' victor', 'email': 'zz@zz.zz'}) >>> form.is_valid() True >>> form.cleaned_data {'name': u'Victor', 'email': u'zz@zz.zz'} # min_length constraint is checked after strip, so it is imposible now to shut up validator with # dummy spaces >>> form = PersonForm({'name': ' E ', 'email': 'zz@zz.zz'}) >>> form.is_valid() False >>> form.errors {'name': [u'Ensure this value has at least 2 characters (it has 1).']} # max_length constraint is checked after strip as well >>> form = PersonForm({'name': ' Victor ', 'email': 'zz@zz.zz'}) >>> form.is_valid() True """} if __name__ == "__main__": import doctest doctest.testmod()