django-allauth:如何正确使用email_confirmed信号将用户设置为活动状态

17

另一篇帖子中,我提到我正在尝试使用allauth的email_confirmed信号将已确认用户的is_active字段更改为true。然而,以下代码给我抛出了异常“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()

我尝试重新处理这个问题,但仍然遇到了类似的异常:“找不到匹配的电子邮件地址。”

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()

这里是回溯信息:

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.

这让我感到困惑,因为我可以在我的数据库中的用户表和“电子邮件地址”表中检查电子邮件地址字段,并且它们似乎都有匹配的电子邮件地址。 能提供帮助吗?

2个回答

27

结果发现由email_confirmed信号返回的email_address实际上不是包含地址的字符串,而是一个对象--allauth.account.models.EmailAddress。从文档中并没有非常清楚地表明这一点,但很高兴现在已经解决了。最终起作用的代码是:

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

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

    user.save()

8
更简洁的写法:user = email_address.split('@')[0]。该代码的作用是从电子邮件地址中提取出用户名,赋值给变量user。 - fmalina
谢谢,对我有用!实际上,在Django 1.9中第一个参数是信号(signal),也许'request'这个名称有些误导。 - mrooney

6
我在尝试将AllAuth的信号设置为我的CustomUser模型时,发现了这个页面。通过一些调试和持续搜索,我找到了一个关于此主题的旧GitHub线程:https://github.com/pennersr/django-allauth/issues/347。他的解决方案对我有效。
我将接收器函数的位置从应用程序/signals.py更改为应用程序/models.py
显然,默认情况下,AppConfig类的ready()函数会导入models.py文件,但需要手动将signals.py文件添加到您的apps.py文件中:
from django.apps import AppConfig


class NameOfAppConfig(AppConfig):
    name = 'NameOfApp'

    def ready(self):
        import NameOfApp.signals

无论如何,在文档中很容易忽略这一点。我猜在未来的Django版本中,他们会默认包含一个signals.py文件并自动整合它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接