Сохранение фотографии Facebook в Django Model (REST Social Oath2)
Этот вопрос касается автоматического сохранения изображений профиля Facebook в модели Django с использованием библиотеки https://github.com/PhilipGarnero/django-rest-framework-social-oauth2.
Изменить: Есть 2 способа решить этот вопрос: сохранить URL-адрес изображения в CharField()
или сохраните само изображение, используя ImageField()
, Оба решения подойдут.
Вышеупомянутая библиотека позволяет мне создавать и аутентифицировать пользователей, используя токены на предъявителя. У меня есть созданная модель профиля:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='userprofile')
photo = models.FileField(blank=True) # OR
######################################
url = 'facebook.com{user id}/picture/'
photo = models.CharField(default=url)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.userprofile.save()
Который автоматически создает профили пользователей для каждого пользователя. Теперь я хотел бы добавить следующий код, чтобы сохранить фотографию из Facebook. API Facebook требует user id
чтобы получить эту картину.
photo = 'https://facebook/{user-id}/picture/'
UserProfile.objects.create(user=instance, photo=photo)
Выше не работает, потому что
1) Я не могу понять, где взять user id
от.
2) Изображение не может быть сохранено таким образом, мне нужно преобразовать его в байты или каким-либо другим способом.
2 ответа
Для этого есть ОЧЕНЬ простое решение. Используйте конвейеры python-social-auth.
То, как работает эта вещь, так же, как middleware
, вы можете добавить на странице настроек в SOCIAL_AUTH_PIPELINE
раздел функция, которая будет запускаться каждый раз, когда пользователь проходит проверку подлинности с использованием social_django
,
Пример:
На странице настроек добавьте следующее:
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social.pipeline.social_auth.social_user',
'social.pipeline.user.get_username',
'social.pipeline.user.create_user',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details',
'home.pipeline.save_profile',
)
смотреть на home.pipeline.save_profile
это новый трубопровод в home.pipeline
файл. (Измените его в свою папку пользовательского модуля)
Там (home.pipeline
) добавить следующее:
from .models import UserProfile
def save_profile(backend, user, response, *args, **kwargs):
if backend.name == "facebook":
UserProfile.objects.create(
user=user,
photo_url=response['user']['picture']
)
Это пример. Вам нужно изменить его для получения / обновления, если пользователь уже вошел в систему. Также попробуйте поиграть с response
аргумент, там могут быть разные данные, которые вы можете использовать там.
И последнее, не забудьте добавить picture
Атрибут в ваших настройках:
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id, name, email, picture'
}
http://python-social-auth.readthedocs.io/en/latest/backends/facebook.html
https://godjango.com/122-custom-python-social-auth-pipeline/
Приведенные выше ответы могут не работать (у меня это не сработало), поскольку URL-адрес профиля facebook больше не работает без токена доступа. Следующий ответ сработал для меня.
def save_profile(backend, user, response, is_new=False, *args, **kwargs):
if is_new and backend.name == "facebook":
# The main part is how to get the profile picture URL and then do what you need to do
Profile.objects.filter(owner=user).update(
imageUrl='https://graph.facebook.com/{0}/picture/?type=large&access_token={1}'.format(response['id'],response['access_token']))
добавить в пайплайн в settings.py,
SOCIAL_AUTH_PIPELINE+ = ('<full_path>.save_profile')