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

标签 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 文档 allauth.socialaccount.signals.pre_social_login(request,social_login) 中找到了这个信号,这表明我可以检查用户是否已使用社交帐户注册,但是我如何将它与我的 create_user_profile 函数一起使用?我想到的步骤是首先创建我所做的个人资料,然后检查用户是否使用社交帐户注册,如果他们这样做了,那么 user_avatar 使用他们的 Instagram 个人资料图片,如果没有,它将保持为没有。

作为一个优点,我知道我可以使用 {{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!

最佳答案

我已经为 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'

因此,此代码只会在新的社交帐户注册过程中被调用,获取头像网址,下载并保存在您的 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)

关于python - django-allauth:检查用户是否使用社交帐户注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31083385/

相关文章:

python - 为嵌套字典中的每个键/值对返回最低值(和关联键)

python - 使用 Django 的 Cron 示例

python - Instagram 检测 python 请求

Android 深度链接到 Instagram 应用

python - 设置 Pyramid Web 框架 | FCGI 共享主机

python - 以默认 ID 作为参数包含的不起作用

python - 从子进程实时捕获标准输出和相机帧

python - 如何将 XML 放入 HTML 模板中? python /Django

javascript - 如何通过 AJAX post 请求将两个依赖下拉列表的值发送到 Django View ?

iOS Swift - 在 Instagram 上分享字幕