The current project I'm working has at the time of writing 20 different forms (90% model forms) instantiated in different scenarios. Django doesn't automatically strip whitespace in text based fields. So instead of doing this:
class ContactMarketingForm(forms.ModelForm):
class Meta:
model = ContactMarketing
exclude = ('contact',)
def clean_notes(self):
return self.cleaned_data['notes'].strip()
def clean_name(self):
return self.cleaned_data['name'].strip()
Instead I wrote a common class for all of my form classes to use:
class _BaseForm(object):
def clean(self):
for field in self.cleaned_data:
if isinstance(self.cleaned_data[field], basestring):
self.cleaned_data[field] = self.cleaned_data[field].strip()
return self.cleaned_data
class BaseModelForm(_BaseForm, forms.ModelForm):
pass
class ContactMarketingForm(BaseModelForm):
class Meta:
model = ContactMarketing
exclude = ('contact',)
Now all text inputs and textareas are automatically whitespace stripped. Perhaps useful for other Djangonauts.
Comments
clean() is called after the individual fields have been validated and so it would not solve, for example, extra whitespace at the end of a password. I like to override full_clean() instead.
def full_clean(self):
stripped_data = {}
for k, v in self.data.items():
stripped_data[k] = v.strip()
self.data = stripped_data
super(LoginForm, self).full_clean()
To correct Kyle: if you override self.data you need to be careful about preserving any lists in the QueryDict. Therefore, Kyle's version should be something like (with appropriate indentation...):
{{{
def full_clean(self):
"Strip whitespace automatically in all form fields"
data = self.data.copy()
for k, vs in self.data.lists():
new_vs = []
for v in vs:
new_vs.append(v.strip())
data.setlist(k, new_vs)
self.data = data
super(BaseForm, self).full_clean()
}}}