django-allauth:检查用户是否使用社交帐户注册

时间:2015-06-26 23:04:56

标签: python django instagram django-allauth profile-picture

所以我在我的应用程序中集成了django-allauth,现在用户可以通过Instagram登录了。假设我有一个名为UserProfile的模型,它有一个字段

user_avatar = models.ImageField(upload_to='profile_images', blank=True, default=None)

有了这个,我有一个信号,一旦新用户注册就会创建一个用户配置文件:

def create_user_profile(sender, instance, created, **kwargs):
     if created:
         UserProfile.objects.create(user=instance)
 post_save.connect(create_user_profile, sender=User)

通常当用户注册user_avatar为空时,因为默认设置为None,现在我想添加信号(如果这是正确的方式),检查用户是否通过签名创建了他的帐户在使用Instagram,去获取他的个人资料图片并在user_avatar中使用它。我认为这是可能的https://instagram.com/developer/endpoints/users/,但由于我是python和django中的一个完整的菜鸟,我不知道如何做到这一点。

所以我从django-allauth docs allauth.socialaccount.signals.pre_social_login(request, social_login)发现了这个信号,所以这说明我可以检查用户是否已使用社交帐户注册,但我如何将其与create_user_profile函数一起使用?我想到的步骤是首先创建我做的配置文件,然后检查用户是否使用社交帐户注册,如果他们确实使用了他们的Instagram个人资料图片的user_avatar,如果没有,它将保持为无。

作为一个优点,我知道我可以使用{{user.socialaccount_set.all.0.get_avatar_url}}在模板中获取用户社交帐户个人资料图片,但我不想通过模板进行,而不是通过最好的模型进行方式。

这可能看起来很愚蠢,但我试了一下,试图找出一些东西(这是新手认为会起作用的,我认为这是我的头脑,因为我不知道这是如何工作的)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)
        def pre_social_login(request, social_login):
            user_logged_social = social_login.account.user
            if user_logged_social:
                UserProfile.objects.get(user_avatar=user_logged_social.profile_picture)
            else:
                pass
post_save.connect(create_user_profile, sender=User)

更新 在@bellum的帮助下工作了!谢谢!

以下是我使用的代码:

models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name="profile")
    user_avatar = models.ImageField(upload_to='profile_images'
                                blank=True,
                                default=None)


    def __unicode__(self):
        return self.user.username

    class Meta:
        verbose_name_plural = "User Profiles"

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)

3utils.py

def download_file_from_url(url):
    # Stream the image from the url
    try:
        request = requests.get(url, stream=True)
    except requests.exceptions.RequestException as e:
        # TODO: log error here
        return None

    if request.status_code != requests.codes.ok:
        # TODO: log error here
        return None

    # Create a temporary file
    lf = tempfile.NamedTemporaryFile()

    # Read the streamed image in sections
    for block in request.iter_content(1024 * 8):

        # If no more file then stop
        if not block:
            break

        # Write image block to temporary file
        lf.write(block)

    return files.File(lf)

class SocialAccountAdapter(DefaultSocialAccountAdapter):
    def save_user(self, request, sociallogin, form=None):
        user = super(SocialAccountAdapter, self).save_user(request, sociallogin, form)

        url = sociallogin.account.get_avatar_url()
        avatar = download_file_from_url(url)
        if avatar:
            profile = user.profile  # access your profile from user by correct name
            profile.user_avatar.save('avatar%d.jpg' % user.pk, avatar)
        return user

settings.py

SOCIALACCOUNT_ADAPTER = 'main.s3utils.SocialAccountAdapter'

在我的模型中注册时创建个人资料的信号保持不变,只添加了一个SocialAccountAdapter!

1 个答案:

答案 0 :(得分:2)

我为Facebook提供程序完成了相同的任务。 allauth提供了以另一种方式实现此目的的可能性。我认为每次用户登录系统时都不需要获取头像。如果是,那么你可以覆盖这样的类:

from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

class SocialAccountAdapter(DefaultSocialAccountAdapter):
    def save_user(self, request, sociallogin, form=None):
        user = super(SocialAccountAdapter, self).save_user(request, sociallogin, form)

        url = sociallogin.account.get_avatar_url()

        avatar = download_file_from_url(url)  # here you should download file from provided url, the code is below
        if avatar:
            profile = user.user_profile  # access your profile from user by correct name
            profile.user_avatar.save('avatar%d.jpg' % user.pk, avatar)

        return user

您应该将此行添加到您的配置中:SOCIALACCOUNT_ADAPTER = 'path-to-your-adapter.SocialAccountAdapter'

结果只会在新的socialaccount注册过程中调用此代码,获取头像网址,下载并保存在User模型中。

import requests
import tempfile

from django.core import files

def download_file_from_url(url):
    # Stream the image from the url
    try:
        request = requests.get(url, stream=True)
    except requests.exceptions.RequestException as e:
        # TODO: log error here
        return None

    if request.status_code != requests.codes.ok:
        # TODO: log error here
        return None

    # Create a temporary file
    lf = tempfile.NamedTemporaryFile()

    # Read the streamed image in sections
    for block in request.iter_content(1024 * 8):

        # If no more file then stop
        if not block:
            break

        # Write image block to temporary file
        lf.write(block)

    return files.File(lf)