progammist
Сәуір 24, 2020, 3:41 Т.Қ.

Вывод изображения-аватара пользователя при авторизации VK (Social Auth Django)

social auth, django

И так, появилась задача - выводить аватар пользователя при авторизации через соц. сети. Что в данный момент:

• Настроил авторизацию по гайду Как добавить аутентификацию через социальные сети. ВКонтакте
• Авторизация пользователя проходит успешно
• Добавляем настройку SOCIAL_AUTH_PIPELINE в settings.py
• Добавил функцию (отдельно) которая получает ссылку аватарки при авторизации:

settings.py

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',
    'blog.pipeline.get_avatar', #Указываем путь, где лежит функция получения аватара.
)

pipeline.py

def get_avatar(backend, response, user=None, *args, **kwargs):

    url = None

    if backend.name == 'vk-oauth2':
        url = response.get('photo', '')

    if url:
        user.avatar = url
        user.save()
        print (user.avatar)

В консоле получаем ссылку на изображение пользователя, который проходит авторизацию/аутентификацию:

https://sun9-2.userapi.com/c857628/v857628128/1e4d00/9v4lVL5AESM.jpg

Картинку получили. Собсна в чем пробелмы:

Не могу вывести в шаблон результат этой функции. Модификации User нет, есть только Profile:

models.py

class Profile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics',)

    def __str__(self):
        return f'{self.user.username} Profile'

    def save(self, *args, **kwargs):
        super(Profile, self).save(*args, **kwargs)

Вопросы:

Как мне расширить модель User, чтобы появилась возможность сохранять полученную ссылку на изображение к текущему пользовтаелю?
Как мне вывести/получать доступ в шаблоне к этой переменной/ссылке на изображение?

Буду благодарен за любую помощь

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

8
progammist
  • Сәуір 24, 2020, 3:59 Т.Қ.
  • (өңделген)

Попробовал в модели Profile добавить поле avatar:

class Profile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(User,default='default.jpg', upload_to='profile_pics',)
    avatar = models.CharField(max_length=100, null=True, blank=True)

    def __str__(self):
        return f'{self.user.username} Profile'

Как мне изменить соответственно функцию?

    Evgenii Legotckoi
    • Сәуір 24, 2020, 5:03 Т.Қ.
    • Жауап шешім ретінде белгіленді.

    Пока я ещё не вернулся домой, и не посмотрел переопределение модели User, вопрос в догонку. В каком месте кода вызываете метод get_avatar ?

    А так, раз уж вы в Profile залили avatar поле, то ту функцию я бы переписал так

    def get_avatar(backend, response, user=None, *args, **kwargs):
    
        url = None
    
        if backend.name == 'vk-oauth2':
            url = response.get('photo', '')
    
        if url:
            user.profile.avatar = url
            user.profile.save()
            print (user.profile.avatar)
    

    Ну и в шаблоне попробуйте вызывать так

    <img src="{{user.profile.avatar}}">
    
      progammist
      • Сәуір 24, 2020, 8:56 Т.Қ.
      • (өңделген)

      Функция get_avatar указывается в settings.py в настройке SOCIAL_AUTH_PIPELINE () . Насколько я понимаю, таким образом мы указываем пользовательскую обработку в конце обработки аутентификации. Добавил более подробно в описание вопроса.

      Вам большое спасибо за помощь - всё работает!

        Владислав Меленчук
        • Сәуір 26, 2020, 2:08 Т.Ж.

        А не подскажите, как реализовать тоже самое только allauth? User переопределена, имеется avatar загрузка.

          Владислав Меленчук
          • Мамыр 11, 2020, 12:31 Т.Ж.
          • (өңделген)

          Снова вернусь в эту тему. В общем как-то раз я сделал всё, что написано выше рабочим на сайте при авторизации юзера через вк.
          Но вот буквально сегодня решил повторить, словил неудачу. Вот в таком виде:

          Django Version: 3.0.6
          Exception Type: OSError
          Exception Value:    
          [Errno 22] Invalid argument: 'C:\\Project\\OSPanel\\domains\\Django\\media\\https:\\sun9-42.userapi.com\\c855016\\v855016451\\21e884\\pu7jMGrfo38.jpg?ava=1'
          Exception Location: C:\Project\OSPanel\domains\Django\venv\lib\site-packages\PIL\Image.py in open, line 2843
          Python Executable:  C:\Project\OSPanel\domains\Django\venv\Scripts\python.exe
          
          

          Зачем создается такой путь? Юзер абстрактный, но есть ещё вот такая фича:

              # Уменьшаем изображение и размер
              def save(self, *args, **kwargs):
                  super(User, self).save(*args, **kwargs)
                  # Выбор картинки
                  img = Image.open(self.avatar.path)
                  # Условие
                  if img.height > 300 or img.width > 300:
                      output_size = (300, 300)
                      img.thumbnail(output_size)
                      img.save(self.avatar.path)
          

          Без неё картинка работает. Но опять же, только через {{ user.avatar }}, а простые (загруженные) авки не работает как надо. Т.е они работают только с {{ user.avatar.url }}

            progammist
            • Мамыр 11, 2020, 12:46 Т.Ж.
            • (өңделген)

            не совсем понял вопрос, но как вариант - я у себя прверяю в шаблоне, если юзер авторизован через соц. сети то выводим урл, если нет - обычное фото

              Владислав Меленчук
              • Мамыр 11, 2020, 12:50 Т.Ж.

              А какой условие у вк?

                progammist
                • Мамыр 11, 2020, 12:59 Т.Ж.
                • (өңделген)

                я проверяю не конкретно по соц. сети а по бекенду авторизации.То есть, если авторизация обычная или нет (соц. сети). В моём случае:

                {% if user.is_authenticated and not backends.associated %}
                

                Какая соц.сеть роли не играет, потому что все-равно получаю урл

                  Пікірлер

                  Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                  Кіріңіз немесе Тіркеліңіз