Django-allauth获取头像个人资料照片

14

我正在使用django-rest-authdjango-allauth来实现用户注册/登录,使用的是用户的Facebook个人资料。

目前,我可以获取一些来自Facebook的标准信息(对于所有授权默认情况下)。

有没有可能获取头像照片列表?如何在allAuth中实现它?

3个回答

29

如果你想在 Django 模板中获取头像图片:

<img src="{{ user.socialaccount_set.all.0.get_avatar_url }}" />

这就是你想要做的吗?


有什么办法可以缓存它们吗?每次加载页面时实时调用它们会很昂贵。 - Özer
@ÖzerS. 你能详细解释一下吗?它为什么贵?如果在自己的服务器上缓存,那不是更贵吗?与让Facebook的服务器传递相比。 - daglundberg
@Daggepagge 每当有人打开使用此代码片段的页面时,您的服务器将联系 Facebook 并获取数据。这通常需要一秒钟左右,因此如果没有使用 ajax,则页面将在获取数据后才呈现。缓存仅存储了 URL 一次,并直接从您的服务器检索它,省去了您需要联系 Facebook 的 1 秒延迟。 - Özer
3
@ÖzerS。这是不正确的。调用get_avatar_url只会格式化一个URL,你可以将其传递给img标签。它不会执行任何HTTP请求。它将像任何其他普通图像一样加载图像。 - Marcus Lind
你会如何循环遍历这个程序,以便将头像/个人资料图片显示给其他用户? - Vicente Antonio G. Reyes
我知道回答这个问题已经很晚了,但如果你仍然感兴趣,我有一个想法。您可以自定义用户模型以具有头像字段。然后,如果社交帐户连接,它可以获取该URL并将其设置为yourusermodel.avatar。这样,您将从自己的服务器获取URL。@ÖzerS. - Kenan

13

让我快速描述一下我是怎么做到的(使用了all_auth和rest_auth)。

基本上,'allauth => socialaccount' 提供了user_signed_upuser_logged_in信号。因此,您需要捕获它们并获取sociallogin对象的额外数据,并填充您的avatar_url。

步骤1:创建一个UserProfile模型:(用于存储avatar_url)

#models.py
try:
    from django.utils.encoding import force_text
except ImportError:
    from django.utils.encoding import force_unicode as force_text

class UserProfile(models.Model):
    user = models.OneToOneField(User, primary_key=True, verbose_name='user', related_name='profile')
    avatar_url = models.CharField(max_length=256, blank=True, null=True)

    def __str__(self):
        return force_text(self.user.email)

    class Meta():
        db_table = 'user_profile'

第二步:捕获 'user_signed_up' 信号并填充`avatar_url'

# signals.py

from allauth.account.signals import user_signed_up, user_logged_in

@receiver(user_signed_up)
def social_login_fname_lname_profilepic(sociallogin, user):
    preferred_avatar_size_pixels=256

    picture_url = "http://www.gravatar.com/avatar/{0}?s={1}".format(
        hashlib.md5(user.email.encode('UTF-8')).hexdigest(),
        preferred_avatar_size_pixels
    )

    if sociallogin:
        # Extract first / last names from social nets and store on User record
        if sociallogin.account.provider == 'twitter':
            name = sociallogin.account.extra_data['name']
            user.first_name = name.split()[0]
            user.last_name = name.split()[1]

        if sociallogin.account.provider == 'facebook':
            f_name = sociallogin.account.extra_data['first_name']
            l_name = sociallogin.account.extra_data['last_name']
            if f_name:
                user.first_name = f_name
            if l_name:
                user.last_name = l_name

            #verified = sociallogin.account.extra_data['verified']
            picture_url = "http://graph.facebook.com/{0}/picture?width={1}&height={1}".format(
                sociallogin.account.uid, preferred_avatar_size_pixels)

        if sociallogin.account.provider == 'google':
            f_name = sociallogin.account.extra_data['given_name']
            l_name = sociallogin.account.extra_data['family_name']
            if f_name:
                user.first_name = f_name
            if l_name:
                user.last_name = l_name
            #verified = sociallogin.account.extra_data['verified_email']
            picture_url = sociallogin.account.extra_data['picture']

    user.save()
    profile = UserProfile(user=user, avatar_url=picture_url)
    profile.save()        
希望这能帮助到你。

2
它显示错误: Signal receivers must accept keyword arguments (**kwargs). 函数原型应该像这样: social_login_fname_lname_profilepic(sociallogin, user, **kwargs): - Ahtisham

0

如果您不想使用Django信号,您可以从allauth.socialaccount.adapter扩展DefaultSocialAccountAdapter并覆盖populate_user

from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.account.utils import user_field


class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
    def populate_user(self, request, sociallogin, data):
        user = super().populate_user(request, sociallogin, data)
        try:
            picture = sociallogin.account.extra_data['picture']
            user_field(user, "profile_photo", picture)
        except (KeyError, AttributeError):
            pass
        return user

请注意,您还应该在settings.py中更改DefaultSocialAccountAdapter

SOCIALACCOUNT_ADAPTER = 'some_app.path.to.CustomSocialAccountAdapter'

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