Пользовательский метод сохранения изображений/аватаров в Django — как использовать

Итак, я пытаюсь немного сжать изображения, а также некоторые другие операции. У меня было несколько вопросов... У меня есть следующий метод save() для моего пользовательского класса:

class User(AbstractBaseUser, PermissionsMixin):
    ...
    avatar = models.ImageField(storage=SITE_UPLOAD_LOC, null=True, blank=True)

    def save(self, *args, **kwargs):
        if self.avatar:
            img = Img.open(BytesIO(self.avatar.read()))

            if img.mode != 'RGB':
                img = img.convert('RGB')

            new_width = 200
            img.thumbnail((new_width, new_width * self.avatar.height / self.avatar.width), Img.ANTIALIAS)
            output = BytesIO()
            img.save(output, format='JPEG', quality=70)
            output.seek(0)
            self.avatar= InMemoryUploadedFile(file=output, field_name='ImageField', name="%s.jpg" % self.avatar.name.split('.')[0], content_type='image/jpeg', size=, charset=None)

        super(User, self).save(*args, **kwargs)

У меня было два вопроса:

  1. Лучший способ удалить старый файл аватара при сохранении, если существует предыдущий аватар
  2. Что мне передать в InMemoryUploadedFile для размера kwarg? Это размер файла? в какой единице/(ах)?

person GCien    schedule 15.02.2018    source источник
comment
Первый вопрос является дубликатом этого: stackoverflow.com/questions/2878490/ Задавайте только один вопрос за раз. Если у вас есть два вопроса, задайте их отдельно.   -  person Håken Lid    schedule 16.02.2018
comment
Возможный дубликат Как удалить старое изображение при обновлении ImageField?   -  person Håken Lid    schedule 16.02.2018


Ответы (2)


Вам нужно получить размер файла. Попробуй это:

import os

size = os.fstat(output.fileno()).st_size

Вы можете прочитать это о том, как получить размер файла: https://docs.python.org/3.0/library/stat.html

и за удаление старого автара. Согласно вашему коду, это внешний ключ, поэтому перед сохранением вы можете проверить, существует ли уже автар, и поэтому вы можете его удалить. Добавьте этот код строки после output.seek(0) этой строки:

if self.avtar:
    self.avtar.delete()
person Diksha    schedule 16.02.2018

Вам нужен размер в байтах.

Вы можете получить размер объекта BytesIO в байтах следующим образом.

size = len(output.getvalue())
person Håken Lid    schedule 16.02.2018