GCien
GCien

Reputation: 2349

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

So, I'm trying to do a little bit of compression of images as well as some other operations. I had a few questions...I have the following save() method for my user 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)

I had two questions:

  1. Best way for deleting the old avatar file on save, if a previous avatar exists
  2. What do I pass into InMemoryUploadedFile for the size kwarg? Is this the size of the file? in what unit/(s)?

Upvotes: 1

Views: 553

Answers (2)

Diksha
Diksha

Reputation: 474

You need to get file size. Try this:

import os

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

You can read this for how to get file size: https://docs.python.org/3.0/library/stat.html

and for deleting old avtar. According to your code it is foreign key hence before saving you can check if avtar is already exists and so yoy can delete it. Add this lines code after output.seek(0) this line:

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

Upvotes: 1

Håken Lid
Håken Lid

Reputation: 23084

What you want is the size in bytes.

You can get the byte size of a BytesIO object like this.

size = len(output.getvalue())

Upvotes: 1

Related Questions