所以我在我的应用程序中集成了 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/