python - /social/complete/facebook/ 处的 social_django TypeError 需要一个类似字节的对象,而不是“元组”
问题描述
我正在使用 social_django 进行 Facebook 登录。当用户使用 facebook 登录时,我想拥有 facebook 的个人资料照片。但是,当我尝试使用 facebook 登录时出现此错误;
/social/complete/facebook/a 字节类对象的类型错误是必需的,而不是“元组”
我已经设法将图片(Facebook 给我的 url 作为回应)下载到我的 media/profile_pics 文件夹,但我无法将它保存到该人的个人资料图片中。我认为问题来自 ImageField 和 FileField 困境,但我无法解决。
我在网上尝试了许多解决方案,但没有帮助。感谢您在高级方面的任何帮助。
设置.py
#social_django
AUTHENTICATION_BACKENDS = (
'social_core.backends.github.GithubOAuth2', #github
'social_core.backends.twitter.TwitterOAuth', #twitter
'social_core.backends.facebook.FacebookOAuth2', #facebook
'django.contrib.auth.backends.ModelBackend', #default django backend
# For Google Authentication
'social.backends.google.GoogleOpenId',
'social.backends.google.GoogleOAuth2',
'social.backends.google.GoogleOAuth',
'apps.users.backend.EmailOrUsernameModelBackend', # loging with email or username
)
#social_django
SOCIAL_AUTH_FACEBOOK_KEY = '*****************' # App ID
SOCIAL_AUTH_FACEBOOK_SECRET = '***************' # App Secret
SOCIAL_AUTH_FACEBOOK_SCOPE = [
'email' ,
'user_location',
'user_hometown',
'user_birthday',
'user_friends',
'public_profile',
]
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id,name,email, gender, birthday, link, location, hometown, first_name, last_name, picture'
}
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'first_name', 'email']
#social_django
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'apps.users.pipeline.save_account',
'apps.users.pipeline.save_profile_picture',
)
#social_django
SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy'
SOCIAL_AUTH_STORAGE = 'social_django.models.DjangoStorage'
模型.py
class Account(AbstractBaseUser):
email = models.EmailField(max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last_login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
company = models.CharField(default='', max_length=200, help_text='In order to share the application with other users; you need to provide a valid company information', blank=True, null=True)
phone = PhoneNumberField('Phone Number', default='', help_text='Kindly use the global formatting without spaces (+90 531 531 53 53 = +905315315353)', unique=True, blank=True, null=True)
first_name = models.CharField(max_length=100, blank=True, null=True)
last_name = models.CharField(max_length=100, blank=True, null=True)
GENDER_LIST=(
('Male', 'Male'),
('Female', 'Female')
)
gender = models.CharField(max_length=100, choices=GENDER_LIST, blank=True, null=True)
birthday = models.DateField(help_text='Kindly provide a global date formatting as follows: (YYYY-MM-DD)', auto_now=False, blank=True, null=True)
country = models.ForeignKey(Country, on_delete=models.SET_NULL, blank=True, null=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, blank=True, null=True)
district = models.CharField(max_length=100, blank=True, null=True)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
slug = models.SlugField(max_length=200, blank=True, null=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = [] #username and password are required by default
objects = AccountManager() # tells this Account database that; the manager database which is in the top AccountManager
def __str__(self):
return f'{self.email}'
def has_perm(self, perm, obj=None): # has permissions; if user is an admin; he can change stuff in the database
return self.is_admin
def has_module_perms(self, app_label): # has module permissions;
return True
# return self.is_admin
def get_absolute_url(self):
return reverse('account_detailview', kwargs={'pk': self.pk})
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
def email_user(self, subject, message, from_email=None): #Sends an email to this User.
send_mail(subject, message, from_email, [self.email])
管道.py
from requests import request, HTTPError
from django.core.files.base import ContentFile
import urllib.request
from urllib.request import urlopen
import os
from django.core.files import File
def save_profile_picture(backend, user, response, details, *args,**kwargs):
account = Account.objects.filter(email=response['email']).first()
if backend.name == 'facebook':
url = response['picture']['data']['url']
os.chdir('media/profile_pics')
# if url:
# avatar = urlopen(url).read()
# fout = open(account.username+'.jpg', "wb") #filepath is where to save the image
# fout.write(avatar)
# fout.close()
# # account.image = url_to_image # depends on where you saved it
# # account.save()
downloaded_pic = urllib.request.urlretrieve(url, account.username + ".jpg")
print("TYPE OF PICTURE --------------------------------------------------------")
print(type(downloaded_pic))
account.image.save(account.username + ".jpg", ContentFile(downloaded_pic))
account.save()
有所有的追溯
TypeError at /social/complete/facebook/
a bytes-like object is required, not 'tuple'
Request Method: GET
Request URL: http://localhost:8000/social/complete/facebook/?granted_scopes=user_birthday%2Cuser_hometown%2Cuser_location%2Cuser_friends%2Cemail%2Cpublic_profile&denied_scopes&code=AQD8CNhL-JVKC41Go2Vy65rRMMo3EnKWdsgwOa8idyKsgYFLPKVHL3r7pkOSjWzl_b_GCr9-vhPpAWrxgYgIFHwILStxfaA3KgoX5VU6pfdnukk0D1RgoQaVvaAA0DLbqJ479srSeXEDLgWvqQ3X9Ndqs-0smd1ClclWkz1SnQJ8jqCEPq2YrFH4yqCBgCy5tJs1Xqyjd494VrcEsYZ_NkcLdzIUFQRDpGkttz4yRDc3wkzMG67uJefBexAJomGiwTb8XSdGwdtB2koQsfX8gxcAh8eYZBxVmjGDgTV5lEiP_6-d6NH0S8vd0kKiSDDUtpU&state=ORXsv8aaTqk11W1DGNJ6bD8VzGysexDX
Django Version: 3.0.6
Exception Type: TypeError
Exception Value:
a bytes-like object is required, not 'tuple'
Exception Location: C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\files\base.py in __init__, line 127
Python Executable: C:\Users\semih\AppData\Local\Programs\Python\Python38\python.exe
Python Version: 3.8.2
Python Path:
['D:\\SEMİH\\Programming\\Python\\Works\\django norga_asistant deneme 2',
'C:\\Users\\semih\\AppData\\Local\\Programs\\Python\\Python38\\python38.zip',
'C:\\Users\\semih\\AppData\\Local\\Programs\\Python\\Python38\\DLLs',
'C:\\Users\\semih\\AppData\\Local\\Programs\\Python\\Python38\\lib',
'C:\\Users\\semih\\AppData\\Local\\Programs\\Python\\Python38',
'C:\\Users\\semih\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages']
Server time: Fri, 5 Mar 2021 11:08:21 +0000
Traceback Switch to copy-and-paste view
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\exception.py in inner
response = get_response(request) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py in _get_response
response = self.process_exception_by_middleware(e, request) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\views\decorators\cache.py in _wrapped_view_func
response = view_func(request, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\views\decorators\csrf.py in wrapped_view
return view_func(*args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_django\utils.py in wrapper
return func(request, backend, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_django\views.py in complete
return do_complete(request.backend, _do_login, user=request.user, …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\actions.py in do_complete
user = backend.complete(user=user, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\base.py in complete
return self.auth_complete(*args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\utils.py in wrapper
return func(*args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\facebook.py in auth_complete
return self.do_auth(access_token, response, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\facebook.py in do_auth
return self.strategy.authenticate(*args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_django\strategy.py in authenticate
return authenticate(*args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\contrib\auth\__init__.py in authenticate
user = backend.authenticate(request, **credentials) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\base.py in authenticate
return self.pipeline(pipeline, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\base.py in pipeline
out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\social_core\backends\base.py in run_pipeline
result = func(*args, **out) or {} …
▶ Local vars
D:\SEMİH\Programming\Python\Works\django norga_asistant deneme 2\apps\users\pipeline.py in save_profile_picture
account.image.save(account.username + ".jpg", ContentFile(downloaded_pic)) …
▶ Local vars
C:\Users\semih\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\files\base.py in __init__
super().__init__(stream_class(content), name=name) …
▶ Local vars
解决方案
问题是urlretrieve()
它返回一个 (filename, headers) 的元组,因此您需要将返回值分配给一个元组,如下所示:
downloaded_pic, headers = urllib.request.urlretrieve(url, account.username + ".jpg")
即使您不会使用headers
. 这类似于许多人在使用 Django 时遇到的问题Model.objects.get_or_create(...)
,它返回 (instance, created) 的一个元组。
请参阅urllib 文档。
推荐阅读
- c# - 在 Asp Net Core 3.1 中带有列表的“multipart/form-data”返回错误请求
- neo4j - 在 neo4j 中是否可以消除执行第一个查询实例所需的额外时间?
- javascript - 在前端拦截来自外部库的 Web 套接字调用?
- wolfram-mathematica - 为什么我可以通过 ?Global`* 找到 y'[x] 的值
- compilation - 转译器的编译单元的等效名称是什么?
- react-native - react-native-webview 中的地图,如何缩放?
- bash - 使用带有 `bash -c` 的子 shell 来 bash 负通配符
- javascript - 重写这行javascript
- python - 带有多个提交按钮的 Python django
- html - 收音机标签不会换行