Django Forms Validation of fields and Commit to model (Change user e-mail)

30% OFF - 9th Anniversary discount on Entity Framework Extensions until December 15 with code: ZZZANNIVERSARY9


There are already implemented forms within Django to change the user password, one example being SetPasswordForm.

There aren't, however, forms to modify the user e-mail and I think the following example is important to understand how to use a form correctly.

The following example performs the following checks:

  • E-mail have in fact changed - very useful if you need to validate the e-mail or update mail chimp;
  • Both e-mail and confirmation e-mail are the same - the form has two fields for e-mail, so the update is less error prone.

And in the end, it saves the new e-mail in the user object (updates the user e-mail). Notice that the __init__() method requires a user object.

class EmailChangeForm(forms.Form):
    A form that lets a user change set their email while checking for a change in the 
    error_messages = {
        'email_mismatch': _("The two email addresses fields didn't match."),
        'not_changed': _("The email address is the same as the one already defined."),

    new_email1 = forms.EmailField(
        label=_("New email address"),

    new_email2 = forms.EmailField(
        label=_("New email address confirmation"),

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(EmailChangeForm, self).__init__(*args, **kwargs)

    def clean_new_email1(self):
        old_email =
        new_email1 = self.cleaned_data.get('new_email1')
        if new_email1 and old_email:
            if new_email1 == old_email:
                raise forms.ValidationError(
        return new_email1

    def clean_new_email2(self):
        new_email1 = self.cleaned_data.get('new_email1')
        new_email2 = self.cleaned_data.get('new_email2')
        if new_email1 and new_email2:
            if new_email1 != new_email2:
                raise forms.ValidationError(
        return new_email2

    def save(self, commit=True):
        email = self.cleaned_data["new_email1"] = email
        if commit:
        return self.user

def email_change(request):
    form = EmailChangeForm()
    if request.method=='POST':
        form = Email_Change_Form(user,request.POST)
        if form.is_valid():
            if request.user.is_authenticated:
                if form.cleaned_data['email1']  == form.cleaned_data['email2']:
                    user = request.user
                    u = User.objects.get(username=user)
                    # get the proper user
           = form.cleaned_data['email1'] 
                    return HttpResponseRedirect("/accounts/profile/")
        return render_to_response("email_change.html", {'form':form},

Got any Django Question?