Thursday, June 23, 2011

Django forms inheritance

I'm using Django forms and needed to create a form for password reset use case.
It turned out that Django already has a built-in form for this operation, but I needed some extra tweaks on it. In addition, I had 2 use cases which required 2 different validations on the form.
Instead of creating 2 new forms from scratch I decided to use Python's inheritance capabilities and produced the following:

class MyFirstPasswordResetForm (django.contrib.auth.forms.PasswordResetForm):
## Override's Django's email field, since I needed a different error message
email = forms.EmailField(label=_("E-mail"), max_length=75, required=True,
error_messages={'invalid': _(u'Please enter a valid email address')})

## My new field
my_hidden_field = forms.CharField(widget=forms.HiddenInput, required=True)

def clean_email(self):
"""
Calling Django's clean_email function, but overrides Django's error message
"""
try:
return super(MyFirstPasswordResetForm, self).clean_email()
except forms.ValidationError:
raise forms.ValidationError(_("This address was not found in our DB - are you sure this is the email address you used to register?"))

def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
use_https=False, token_generator=default_token_generator):
"""
Overrides Django's save function
"""
## Do some stuff
pass

And this class inherits from it:
class MySecondPasswordResetForm(MyFirstPasswordResetForm):
'''
Inherits "email", "my_hidden_field" and "save" from MyFirstPasswordResetForm
'''
def clean_email(self):
"""
Override just this function.
"""
email = super(MySecondPasswordResetForm, self).clean_email()
## Additonal validations here, specific for MySecondPasswordResetForm

return email


And it saves code duplication, development and testing time !