Search code examples
djangopython-imaging-library

image being re-uploaded when updating object


On my blog post model I override the save method to call a function to compress the image being uploaded. This works as expected. However when I use an update view and make a change to the post the image is then re uploaded to the s3 bucket and replaces the original image on the model.

If i remove all the code from the compress function and just have it return image, when using the update view it does not re upload the image.

How can I prevent the image from being re uploaded when on the updateview.

model:

    def compress(image):
    
    img = Image.open(image)
    img = img.convert("RGB")

    (w, h) = img.size   # current size (width, height)
    if w > 2000:
        new_size = (w//2, h//2)  # new size
        img = img.resize(new_size, Image.ANTIALIAS)
        (w, h) = img.size
        if w > 2000:
            new_size = (w//2, h//2)  # new size
            img = img.resize(new_size, Image.ANTIALIAS)

    im_io = BytesIO() 
    img.save(im_io, 'JPEG', quality=70, optimize=True) 

    new_image = File(im_io, name=image.name)

    return new_image


class Post(models.Model):
    image = models.ImageField(storage=PublicMediaStorage(), upload_to=path_and_rename, validators=[validate_image])
    ....


    def save(self, *args, **kwargs): 
        self.slug = slugify(self.title)

        if self.image:
            # call the compress function
            new_image = compress(self.image)
            # set self.image to new_image
            self.image = new_image

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

view:

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Post
    form_class = PostFormUpdate
    template_name = 'blog/update_post.html'
   
    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user.id == post.author_id:
            return True
        return False

enter image description here


Solution

  • self._state.adding can be used to check if it's the initial save() call.

    def save(self, *args, **kwargs): 
        self.slug = slugify(self.title)
        initial = self._state.adding
    
        if self.image and initial:
            # call the compress function
            new_image = compress(self.image)
            # set self.image to new_image
            self.image = new_image
    
        super(Post,self).save(*args, **kwargs)