Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-allauth: how to properly use email_confirmed signal to set user to active

In another post, I mentioned that I was trying to use allauth's email_confirmed signal to change the is_active field on the confirmed user to true. However, the following code gave me the exception "User matching query does not exist."

from allauth.account.signals import email_confirmed
from django.dispatch import receiver
from django.contrib.auth.models import User

@receiver(email_confirmed)
def email_confirmed_(request, email_address, **kwargs):

    user = User.objects.get(email=email_address)
    user.is_active = True

    user.save()

I tried to re-work this, and still got a similar exception, "EmailAddress matching query does not exist."

from allauth.account.signals import email_confirmed
from django.dispatch import receiver
from django.contrib.auth.models import User
from allauth.account.models import EmailAddress

@receiver(email_confirmed)
def email_confirmed_(request, email_address, **kwargs):

    new_email_address = EmailAddress.objects.get(email=email_address)
    user = User.objects.get(new_email_address.user)
    user.is_active = True

    user.save()

Traceback is here:

Environment:


Request Method: POST
Request URL: http://www.website.com/accounts/confirm-email/5901011619071fce757447ba146fe6312cb27bc0fee34d29665b857b479b49fc/

Django Version: 1.6.1
Python Version: 3.3.2
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'surveys',
'registration',
'django.contrib.sites',
'bootstrap3',
'allauth',
'allauth.account',
'allauth.socialaccount')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/usr/local/lib/python3.3/dist-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.3/dist-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.3/dist-packages/django/views/generic/base.py" in dispatch
  87.         return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.3/dist-packages/allauth/account/views.py" in post
  204.         confirmation.confirm(self.request)
File "/usr/local/lib/python3.3/dist-packages/allauth/account/models.py" in confirm
  111.                                          email_address=email_address)
File "/usr/local/lib/python3.3/dist-packages/django/dispatch/dispatcher.py" in send
  185.             response = receiver(signal=self, sender=sender, **named)
File "/home/username/website/webapp/mysite/views.py" in email_confirmed_
  84.     new_email_address = EmailAddress.objects.get(email=email_address)
File "/usr/local/lib/python3.3/dist-packages/django/db/models/manager.py" in get
  151.         return self.get_queryset().get(*args, **kwargs)
File "/usr/local/lib/python3.3/dist-packages/django/db/models/query.py" in get
  307.                 self.model._meta.object_name)

Exception Type: DoesNotExist at /accounts/confirm-email/5901011619071fce757447ba146fe6312cb27bc0fee34d29665b857b479b49fc/
Exception Value: EmailAddress matching query does not exist.

This is confusing to me, because I can check the email address field in both the user table and the "email addresses" table in my database and they both seem to have matching email addresses. Help would be appreciated!

like image 764
Gravity Grave Avatar asked Jul 17 '14 17:07

Gravity Grave


2 Answers

I found this page while trying to set up a signal from AllAuth to my CustomUser Model.

After some debugging and continued searching, I found an old GitHub thread on the subject: https://github.com/pennersr/django-allauth/issues/347. His solution worked for me.

I changed the location of my receiver function from app/signals.py to app/models.py

Apparently, by default the ready() function of the AppConfig Class imports the models.py file, but a signals.py file needs to be manually added to your apps.py file:

from django.apps import AppConfig


class NameOfAppConfig(AppConfig):
    name = 'NameOfApp'

    def ready(self):
        import NameOfApp.signals

Anyway, it's easy to miss this in the documentation. I'd guess in future Django releases they will include a signals.py file as a default file and incorporate it automatically.

like image 153
crappy_hacker Avatar answered Oct 12 '22 00:10

crappy_hacker


Turns out the email_address returned by the email_confirmed signal isn't actually a string containing the address, but an object -- allauth.account.models.EmailAddress. This wasn't very clear at all from the documentation, but glad it's resolved now. The code that ended up working was:

@receiver(email_confirmed)
def email_confirmed_(request, email_address, **kwargs):

    user = User.objects.get(email=email_address.email)
    user.is_active = True

    user.save()
like image 24
Gravity Grave Avatar answered Oct 12 '22 00:10

Gravity Grave