在django allauth中处理重复的电子邮件地址

时间:2018-01-13 20:10:07

标签: django django-allauth

我想做什么?

我正在尝试通过以下步骤避免重复的电子邮件地址:

  1. 在用户从社交帐户登录我的网站之前,我会检查该电子邮件地址是否已存在。
  2. 如果否,则登录用户,否则请检查以下步骤。

    • 检查注册用户的提供商是否与尝试登录的用户匹配。

    • 如果否,则不允许用户登录,否则登录用户。

  3. 有什么问题?

    我收到以下错误:

    错误: AttributeError at /accounts/twitter/login/callback/ 'QuerySet' object has no attribute 'profile'

    我的代码:

    views.py:

    @receiver(pre_social_login)
    def handleDuplicateEmail(sender, request, sociallogin, **kwargs):
        if sociallogin.account.provider == 'facebook' or sociallogin.account.provider == 'twitter': 
            email_address = sociallogin.account.extra_data['email'] # get email address from fb or twitter social account.
        else:
            email_address = sociallogin.account.extra_data['email-address']  # Get email from linkedin social account.
        users = User.objects.all().filter(email=email_address) # This line is problematic
        if users:  
            if not (users.profile.provider == sociallogin.account.provider):    # Different user is trying to login with already existing user's email address.         
                response = 'Your social account email address is already registered to some account. Please choose a different one.'
                raise ImmediateHttpResponse(render(request, 'index.html', {'type': True, 'response': response}))    # redirect to index template with error message.
    

    models.py:

    class Profile(models.Model):
         user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)        
         provider = models.CharField(max_length=256, blank=True, null=True) # for storing name of provider used to login with.
    

    编辑:

    由于 Facebook Twitter Linkedin 让用户可以选择使用他们的电话号码或电子邮件地址登录,如果他们选择了电话号码,那么因为用户将没有与他们相关联的电子邮件地址来处理这种情况我已经更新了我的代码:

    if sociallogin.account.provider == 'facebook' or sociallogin.account.provider == 'twitter': 
        try:
            email_address = sociallogin.account.extra_data['email']
        except:
            email_address = None # If social account was created on phone number for facebook & twitter
    else:
        try:
            email_address = sociallogin.account.extra_data['email-address'] 
        except:
            email_address = None # If social account was created on phone number or linkedin
    if email_address:        
        users = User.objects.all().filter(email=email_address)
        if users.exists():
            ...
    else:
        response = 'You have not provided an email address in your social account. Please register as local user or use a different social account.'
        raise ImmediateHttpResponse(render(request, 'index.html', {'type': True, 'response': response}))    
    

1 个答案:

答案 0 :(得分:1)

$("#source li").css({"left":"0px","top":"0px"}); 会返回users = User.objects.all().filter(email=email_address),因此您无法在其上调用QuerySet。理论上,此查询可以返回多个.profile个对象。但它也可能包含0个对象(更有可能)。

所以你需要处理这些案件:

User

if users.exists():
    user = users.first()  # assuming there will always only be one user
    if not user.profile.provider == sociallogin.account.provider:
        etc...