Django 中 images/avatars 的自定义保存方法 - 如何使用

Custom save method for images/avatars in Django - how to use

因此,我正在尝试对图像进行一些压缩以及一些其他操作。我有几个问题...我的用户有以下 save() 方法 class:

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 以获取 size kwarg?这是文件的大小吗?在什么单位/(s)?

您需要获取文件大小。试试这个:

import os

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

您可以阅读以下内容了解如何获取文件大小: https://docs.python.org/3.0/library/stat.html

并用于删除旧头像。根据你的代码,它是外键,因此在保存之前你可以检查 avtar 是否已经存在,所以你可以删除它。 在 output.seek(0) 这行之后添加这行代码:

if self.avtar:
    self.avtar.delete()

你想要的是字节大小。

您可以像这样获取 BytesIO 对象的字节大小。

size = len(output.getvalue())