Django中图像/头像的自定义保存方法 - 如何使用

时间:2018-02-15 22:14:41

标签: python django pillow django-1.11

所以,我正在尝试对图像进行一些压缩以及其他一些操作。我有几个问题......我的用户类有以下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. 对于大小kwarg,我应该传递给InMemoryUploadedFile什么?这是文件的大小吗?在什么单位/(s)?

2 个答案:

答案 0 :(得分:1)

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

import os

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

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

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

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

答案 1 :(得分:1)

你想要的是以字节为单位的大小。

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

size = len(output.getvalue())