Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django correctly delete image after updating file

There is a similar question here but that is from 2011 and Django 1.2. Many things have changed since then. I'm using Django 1.9.

I'm wondering how should I do this correctly, without any risks of messing up the filesystem. I have an ImageField in a model:

class CartaMagicPy(models.Model):
    imagen = models.ImageField(null=True, upload_to=ubicar_magicpy)

On a first moment, the image is saved. But then, the user crops the image and I get a new image assigned to the same ImageField.

The old image is not deleted from the filesystem. How can I delete it? The problem is that model_object.imagen.path after being updated contains the path to the new image. And if I delete it before I update it with the new image, I risk that maybe the save could fail and then I end up with no image at all. Is there a combination of post-save signals I could use? Any advice will help.

like image 561
Alejandro Veintimilla Avatar asked Oct 26 '25 19:10

Alejandro Veintimilla


2 Answers

As seen in this answer, "there's an app for that": django-cleanup.

If you prefer to implement it yourself, the accepted answer to the question @raphv linked in the comment gives some good pointers.

A good solution for updated change followup is to use model signals; I tend to use post_init and post_save, in this case to delete the old image file after the change has been made. Something like so:

from django.db.models.signals import post_init, post_save
from django.dispatch import receiver

from myapp.models import CartaMagicPy


@receiver(post_init, sender= CartaMagicPy)
def backup_image_path(sender, instance, **kwargs):
    instance._current_imagen_file = instance.imagen


@receiver(post_save, sender= CartaMagicPy)
def delete_old_image(sender, instance, **kwargs):
    if hasattr(instance, '_current_imagen_file'):
        if instance._current_imagen_file != instance.imagen.path:
            instance._current_imagen_file.delete(save=False)

This also seems to be generally what the linked package above does, plus some additional safety checks and cleanup.

like image 197
tutuDajuju Avatar answered Oct 29 '25 15:10

tutuDajuju


I am not sure, but you can try this

use Django-cleanup

pip install django-cleanup

settings.py

INSTALLED_APPS = ( ... 'django_cleanup', # should go after your apps ... )

like image 38
Raj Shah Avatar answered Oct 29 '25 13:10

Raj Shah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!