如何使用django-allauth提供者信息填充用户个人资料?

19

我正在使用django-allauth进行身份验证系统。 当用户登录时,我需要使用提供者信息(在我的情况下是Facebook)填充配置文件模块。

我尝试使用pre_social_login信号,但我不知道如何从提供者身份验证中检索数据。

from django.dispatch import receiver
from allauth.socialaccount.signals import pre_social_login

@receiver(pre_social_login)

def populate_profile(sender, **kwargs):
    u = UserProfile( >>FACEBOOK_DATA<< )
    u.save()

谢谢!!!

4个回答

25

pre_social_login 信号在用户通过社交认证成功,但登录实际上还没有处理完成时发送。该信号用于社交登录、注册和将其他社交账户连接到一个账户的情况。

因此,在注册完全完成之前发送此信号 - 因此这不是正确的信号。

相反,我建议您使用allauth.account.signals.user_signed_up,它适用于所有用户,包括本地用户和社交用户。

在这个处理程序中,您可以检查附加到用户的任何SocialAccount。例如,如果您想要检查Google+特定数据,请执行以下操作:

user.socialaccount_set.filter(provider='google')[0].extra_data

更新:最新的开发版本通过传递一个sociallogin参数,直接包含所有相关信息(社交账号,令牌等),使此过程变得更加便捷。


我不得不这样使用:kwargs.get('user').socialaccount_set.filter(provider='facebook').extra_data,但是当我这样做时,我会遇到这个错误:AttributeError at /accounts/facebook/login/callback/ 'QuerySet' object has no attribute 'extra_data'。感谢你的回答,伙计!你的应用程序真棒。 - Tomer Simis
糟糕,我的示例有误(我刚刚纠正了它)。我忘记从查询集中选择一个项目([0]),就像这样:".filter(...)[0]..."。 - pennersr
sociallogin参数中的好处可以被访问,例如sociallogin.account.get_provider_display()、sociallogin.account.get_avatar_url()、sociallogin.account.get_profile_url()、sociallogin.account.provider、sociallogin.account.extra_data['screen_name']... - shacker

11

以下是@pennersr解决方案的具体示例:

假设您的个人资料模型具有以下3个字段:first_nameemailpicture_url

views.py:

@receiver(user_signed_up)
def populate_profile(sociallogin, user, **kwargs):    

    if sociallogin.account.provider == 'facebook':
        user_data = user.socialaccount_set.filter(provider='facebook')[0].extra_data
        picture_url = "http://graph.facebook.com/" + sociallogin.account.uid + "/picture?type=large"            
        email = user_data['email']
        first_name = user_data['first_name']

    if sociallogin.account.provider == 'linkedin':
        user_data = user.socialaccount_set.filter(provider='linkedin')[0].extra_data        
        picture_url = user_data['picture-urls']['picture-url']
        email = user_data['email-address']
        first_name = user_data['first-name']

    if sociallogin.account.provider == 'twitter':
        user_data = user.socialaccount_set.filter(provider='twitter')[0].extra_data
        picture_url = user_data['profile_image_url']
        picture_url = picture_url.rsplit("_", 1)[0] + "." + picture_url.rsplit(".", 1)[1]
        email = user_data['email']
        first_name = user_data['name'].split()[0]

    user.profile.avatar_url = picture_url
    user.profile.email_address = email
    user.profile.first_name = first_name
    user.profile.save()         

如果您对每个提供程序中的picture_url变量感到困惑,请查看文档: facebook: picture_url = "http://graph.facebook.com/" + sociallogin.account.uid + "/picture?type=large" 文档 linkedin: picture_url = user_data['picture-urls']['picture-url'] 文档 twitter: picture_url = picture_url.rsplit("_", 1)[0] + "." + picture_url.rsplit(".", 1)[1] 文档 对于rsplit(),请查看这里 希望能对您有所帮助。 :)

2
我会用以下的方式进行操作,并以获取图片URL和Google提供商为例进行讲解。
socialaccount_obj = SocialAccount.objects.filter(provider='google', user_id=self.user.id)
   picture = "not available"
   if len(socialaccount_obj):
            picture = socialaccount_obj[0].extra_data['picture']

请确保导入以下内容:from allauth.socialaccount.models import SocialAccount。

1

有更简单的方法来完成这个任务。

只需将以下内容添加到您的settings.py中。例如,领英...

SOCIALACCOUNT_PROVIDERS = {
'linkedin': {
    'SCOPE': [
        'r_basicprofile',
        'r_emailaddress'
    ],
    'PROFILE_FIELDS': [
        'id',
        'first-name',
        'last-name',
        'email-address',
        'picture-url',
        'public-profile-url',
    ]
}

这些字段会自动跨越。


1
你如何知道哪些 SCOPEPROFILE_FIELDS 键值是可用的? - Flimm
该选项取决于供应商。目前它仅适用于 LinkedIn。 - Rahul Hindocha

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