Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change the "account already exists" message in Django allauth?

When trying to log in with a social account while there already being an account with that email, the following message shows:

An account already exists with this e-mail address. Please sign in to that account first, then connect your Google account.

Now I would like to change that message. At first I tried to override ACCOUNT_SIGNUP_FORM_CLASS = 'mymodule.forms.MySignupForm' and gave it my own raise_duplicate_email_error method, but that method is never called.

The form looks like this:

class SignupForm(forms.Form):
    first_name = forms.CharField()
    last_name = forms.CharField()
    boolflag = forms.BooleanField()

    def raise_duplicate_email_error(self):
        # here I tried to override the method, but it is not called
        raise forms.ValidationError(
            _("An account already exists with this e-mail address."
              " Please sign in to that account."))

    def signup(self, request, user):
        # do stuff to the user and save it 

So the question is: How can I change that message?

like image 812
dan_kaufhold Avatar asked Dec 17 '14 06:12

dan_kaufhold


1 Answers

If you want the raise_duplicate_email_error method to be called you must inherit from a form class that actually calls self.raise_duplicate_email_error()! However you are just inheriting from forms.Form!

Let's take a look at the code of forms.py at https://github.com/pennersr/django-allauth/blob/master/allauth/account/forms.py. We can see that raise_duplicate_email_error is a method of BaseSignupForm (and is called from its clean_email method).

So you need to inherit from either allauth.account.forms.BaseSignupForm or allauth.account.forms.SignupForm (which also inherits from BaseSignupForm and adds some more fieldds to it).

Update after OP's comment (that the BaseSignupForm is derived from the _base_signup_form_class() function, that itself imports the form class defined in the SIGNUP_FORM_CLASS setting ): Hmm you are right. The problem is that the raise_duplicate_email_error and clean_email methods of BaseSignupForm don't call the same-named methods of their ancestors through super (so your raise_duplicate_email_error is never called).

Let's see what the view does: If you have added the line url(r'^accounts/', include('allauth.urls')), to your urls.py (which is the usual thing to do for django-allauth), you'll see the line url(r"^signup/$", views.signup, name="account_signup"), in the file https://github.com/pennersr/django-allauth/blob/13edcfef0d7e8f0de0003d6bcce7ef58119a5945/allauth/account/urls.py and then in the file https://github.com/pennersr/django-allauth/blob/13edcfef0d7e8f0de0003d6bcce7ef58119a5945/allauth/account/views.py you'll see the definition of signup as signup = SignupView.as_view(). So let's override SignupView to use our own form and then use our class view for the account_sigunp !

Here's how to do it:

a. Create your custom view that inherits SignupView and overrides the form class

class CustomFormSignupView(allauth.accounts.views.SignupView):
    form_class = CustomSignupForm

b. Create a custom form that inherits from SignupForm and overrides the email validation message

class CustomSignupForm(allauth.accounts.forms.SignupForm ):
    def raise_duplicate_email_error(self):
        # here I tried to override the method, but it is not called
        raise forms.ValidationError(
            _("An account already exists with this e-mail address."
              " Please sign in to that account."))

c. In your own urls.py add the following after include('allauth.urls') to override the account_signup url

    url(r'^accounts/', include('allauth.urls')),
    url(r"^accounts/signup/$", CustomFormSignupView.as_view(), name="account_signup"),``
like image 166
Serafeim Avatar answered Nov 20 '22 06:11

Serafeim