A Django base class for all your Forms

16 November 2013   2 comments   Django

Mind That Age!

This blog post is 4 years old! Most likely, its content is outdated. Especially if it's technical.

Powered by Fusion×

This has served me well of the last couple of years of using Django:

from django import forms

class _BaseForm(object):
    def clean(self):
        cleaned_data = super(_BaseForm, self).clean()
        for field in cleaned_data:
            if isinstance(cleaned_data[field], basestring):
                cleaned_data[field] = (
                    cleaned_data[field].replace('\r\n', '\n')
                    .replace(u'\u2018', "'").replace(u'\u2019', "'").strip())

        return cleaned_data


class BaseModelForm(_BaseForm, forms.ModelForm):
    pass


class BaseForm(_BaseForm, forms.Form):
    pass

So instead of doing...

class SigupForm(forms.Form):
    name = forms.CharField(max_length=100)
    nick_name = forms.CharField(max_length=100, required=False)

...you do:

class SigupForm(BaseForm):
    name = forms.CharField(max_length=100)
    nick_name = forms.CharField(max_length=100, required=False)

What it does is that it makes sure that any form field that takes a string strips all preceeding and trailing whitespace. It also replaces the strange "curved" apostrophe ticks that Microsoft Windows sometimes uses.

Yes, this might all seem trivial and I'm sure there's something as good or better out there but isn't it a nice thing to never have to worry about doing things like this again:

class SignupForm(forms.Form):
    ...

    def clean_name(self):
        return self.cleaned_data['name'].strip()

#...or...

form = SignupForm(request.POST)
if form.is_valid():
    name = form.cleaned_data['name'].strip()

UPDATE

This breaks some fields, like DateField.

>>> class F(BaseForm):
...     start_date = forms.DateField()
...     def clean_start_date(self):
...         return self.cleaned_data['start_date']
...
>>> f=F({'start_date': '2013-01-01'})
>>> f.is_valid()
True
>>> f.cleaned_data['start_date']
datetime.datetime(2013, 1, 1, 0, 0)

As you can see, it cleans up '2013-01-01' into datetime.datetime(2013, 1, 1, 0, 0) when it should become datetime.date(2013, 1, 1).

Not sure why yet.

Follow @peterbe on Twitter

Comments

Simonas
The “curved” apostrophe (U+2019 RIGHT SINGLE QUOTATION MARK) is actually a preferred symbol for apostrophe in many cases.

See http://unicode.org/Public/UNIDATA/NamesList.txt or https://en.wikipedia.org/wiki/Apostrophe#Unicode
Peter Bengtsson
So it's a standard Unicode character? I thought it was something incorrectly encoded because UTF-8 had troubles with it.
Thank you for posting a comment

Your email will never ever be published


Related posts

Previous:
From Postgres to JSON strings 12 November 2013
Next:
Credit Card formatter in Javascript 19 November 2013
Related by Keyword:
HTML whitespace "compression" - don't bother! 11 March 2013
The awesomest way possible to serve your static stuff in Django with Nginx 24 March 2010
Automatically strip whitespace in Django forms 12 October 2009
Gzip and Slimmer optimization anecdote 30 January 2007
slim, a new free web service for white space optimisation 25 July 2006
Related by Text:
Automatically strip whitespace in Django forms 12 October 2009
EmailInput HTML5 friendly for Django 02 August 2011
Fastest "boolean SQL queries" possible with Django 14 January 2011
My dislike for booleans and that impact on the Django Admin 01 June 2009
When to __deepcopy__ classes in Python 14 March 2012