django-allauth:检查用户是否使用社交帐户注册
django-allauth: Check whether user signed up using a social account
所以我在我的应用程序中集成了 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 个人资料图片,如果没有它会保持 none.
另外,我知道我可以使用 {{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
提供了以另一种方式实现这一目标的可能性。我认为您不需要每次用户登录您的系统时都获得头像。如果是,那么您可以像这样覆盖 class:
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'
。
因此,此代码只会在新社交帐户注册过程中调用,获取头像 url,下载并保存在您的 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)
所以我在我的应用程序中集成了 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 个人资料图片,如果没有它会保持 none.
另外,我知道我可以使用 {{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
提供了以另一种方式实现这一目标的可能性。我认为您不需要每次用户登录您的系统时都获得头像。如果是,那么您可以像这样覆盖 class:
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'
。
因此,此代码只会在新社交帐户注册过程中调用,获取头像 url,下载并保存在您的 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)