How to customize activate_url on django-allauth? How to customize activate_url on django-allauth? django django

How to customize activate_url on django-allauth?


I have managed to make the activation from the frontend by overriding the DefaultAccountAdapter class and overriding the send_mail method as specified in the django-allauth doc :

If this does not suit your needs, you can hook up your own custom mechanism by overriding the send_mail method of the account adapter (allauth.account.adapter.DefaultAccountAdapter)

I first wrote the backend url that I use to confirm an email :

api_patterns = [...url(r'^verify-email/(?P<key>\w+)/$',        confirm_email, name="account_confirm_email"),...]

I then specified the custom adapter and the frontend url in settings.py as follows :

ACCOUNT_ADAPTER = 'API.adapter.DefaultAccountAdapterCustom'URL_FRONT = 'http://localhost:9000/'

And wrote this in the adapter.py from my app :

from allauth.account.adapter import DefaultAccountAdapterfrom django.conf import settingsclass DefaultAccountAdapterCustom(DefaultAccountAdapter):    def send_mail(self, template_prefix, email, context):        context['activate_url'] = settings.URL_FRONT + \            'verify-email/' + context['key']        msg = self.render_mail(template_prefix, email, context)        msg.send()

The activation url sent in the email will now look like : http://127.0.0.1:9000/verify-email/<key>/

I changed the activate_url to the URL_FRONT string I specified in settings.py and appended the key in order to make a get request from the frontend to the url I wrote earlier (Let's say http://localhost:8000/verify-email/<key>). (Previously setting ACCOUNT_CONFIRM_EMAIL_ON_GET to True in order to confirm an email just by doing a get request)


Building on Storm's answer I have a slight improvement (perhaps this wasn't possible when the answer was originally posted). DefaultAccountAdapter has a specific get_email_confirmation_url method that can be overridden to generate the email verification URL and nothing else. The following works well for me. There is no need for an entry in urls.py.

In settings.py

# Repoint this setting to a subclass of the DefaultAccountAdapter # so we can override how it handles account verification to allow # for usage in an SPA context.ACCOUNT_ADAPTER = 'common.accountadapter.CustomAccountAdapter'# An email verification URL that the client will pick up.CUSTOM_ACCOUNT_CONFIRM_EMAIL_URL = "/verifyemail/?key={0}"

In common.accountadapter.py:

from allauth.account.adapter import DefaultAccountAdapterfrom allauth.utils import build_absolute_urifrom django.conf import settingsclass CustomAccountAdapter(DefaultAccountAdapter):    def get_email_confirmation_url(self, request, emailconfirmation):        url = settings.CUSTOM_ACCOUNT_CONFIRM_EMAIL_URL.format(emailconfirmation.key)        ret = build_absolute_uri(            request,            url)        return ret

In my case, django is rooted at "/backend", and a javascript client (in Vue) is rooted at "/". This returns a URL like this, which is handled by the javascript client:

http://localhost/verifyemail/?key=MTc:1h4C9w:b0CIOekBNfirVSt-0-bHOSQQnjk

(localhost is automatically populated from the hostname from the request).


Couldn't find any docs specifying this (sure they must be out there somewhere), but looking at github they just do a URL reverse on "account_confirm_email"

You just need to add an urlpattern with the name="account_confirm_email" param after theirs, like so:

from allauth.account.views import confirm_emailulrpatterns= patterns('',    ...    url(r'^rest-auth/', include('rest_auth.urls')),    url(r'^verify-email/(?P<key>\w+)/$',        confirm_email,        name="account_confirm_email"),)

The problem with this, is that you are now directly addressing the dependency of a dependency. If a newer version of django-restauth doesn't use this, it could break on you.

If you are open to using other libraries, I'm currently using djoser with DRF and have found it pretty straightforward. Perhaps it meets your needs.