Jun 01, 2014 · Updated: Jun 09, 2022 · by Tim Kamanin
In Django, if you delete a model that has Filefield or Imagefield, the related files aren't deleted from the filesystem. You can fix that in two steps:
Add filecleanup
function, that'll take care of deleting files attached to a model:
import os
from django.core.files.storage import default_storage
from django.db.models import FileField
def file_cleanup(sender, **kwargs):
"""
File cleanup callback used to emulate the old delete
behavior using signals. Initially django deleted linked
files when an object containing a File/ImageField was deleted.
Usage:
>>> from django.db.models.signals import post_delete
>>> post_delete.connect(file_cleanup, sender=MyModel, dispatch_uid="mymodel.file_cleanup")
"""
for fieldname in sender._meta.get_all_field_names():
try:
field = sender._meta.get_field(fieldname)
except:
field = None
if field and isinstance(field, FileField):
inst = kwargs["instance"]
f = getattr(inst, fieldname)
m = inst.__class__._default_manager
if (
hasattr(f, "path")
and os.path.exists(f.path)
and not m.filter(
**{"%s__exact" % fieldname: getattr(inst, fieldname)}
).exclude(pk=inst._get_pk_val())
):
try:
default_storage.delete(f.path)
except:
pass
In models.py
, add post_delete
signal to catch model deletion event:
from django.db import models
from django.db.models.signals import post_delete
from .utils import file_cleanup
# ... models code goes here ...
post_delete.connect(
file_cleanup, sender=Image, dispatch_uid="gallery.image.file_cleanup"
)
And that's all. As you see in the example above, my sender is Image model, and when it's get deleted, it'll fire file_cleanup
function that will take care of cleaning up files.
Hey, if you've found this useful, please share the post to help other folks find it: