Automatically delete file in filefield Django 1.3 when object / record deleted

Deleting a model records in Django 1.3 doesn’t followed with delete associated files in FileField. As explained on Django 1.3 CHANGELOG releases :

In earlier Django versions, when a model instance containing a FileField was deleted, FileField took it upon itself to also delete the file from the backend storage. This opened the door to several data-loss scenarios, including rolled-back transactions and fields on different models referencing the same file. In Django 1.3, when a model is deleted the FileField’s delete() method won’t be called. If you need cleanup of orphaned files, you’ll need to handle it yourself (for instance, with a custom management command that can be run manually or scheduled to run periodically via e.g. cron).


There are few way to be able deleting a data models and automatically delete related files. I will using Signals to solve this problem. Because it’s will quick, fast and only short code. For instance :

models.py

1
2
3
4
5
6
from django.db import models

class Schools(models.Model):
    uploader = models.CharField(max_length=255)
    created = models.DateField()
    pdf = models.FileField(max_length=1000)

As explain in Signal Documentation, we can make action before and after records in models deleted. I will use post_delete() which deleting files after record deleted. Using post_delete signals is easy. Just put it method on models.py which sender and kwargs as param. Then we can use default_storage to delete files.

In this example, I will provide deleting PDF files FileField in Django 1.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django.db import models
from django.db.models.signals import post_delete
from django.core.files.storage import default_storage

class Schools(models.Model):
    uploader = models.CharField(max_length=255)
    created = models.DateField()
    pdf = models.FileField(max_length=1000)

# Signals handler for deleting files after object record deleted
# In Django 1.3, delete a record not remove the associated files
def delete_filefield(sender, **kwargs):
    """Automatically deleted files when records removed.
   
    On Django 1.3, removing records will not followed by deleting files.
    Should manually delete PDF using signals post_delete.
    """
    school = kwargs.get('instance')
    #default_storage.delete(school.pdf.path)
    school.storage.delete(school.pdf.path)
post_delete.connect(delete_filefield, School)

Now if I deleted objects models, it will automatically deleted FileField PDF files.

1
2
schools = School.objects.get(id=1)
schools.delete()                     # It will delete FileField
This entry was posted in Django and tagged , . Bookmark the permalink.

6 Responses to Automatically delete file in filefield Django 1.3 when object / record deleted

  1. haineault says:

    A while ago I’ve wrote a generic function that can be bound to a post/pre_delete signal. It does pretty much the same thing as your code, but avoid the need to repeat your function code over and over.

    https://github.com/h3/django-webcore/blob/master/webcore/utils/storage.py#L8

    It just iterate over the model’s fields and take appropriate action if it contains fields that subclass the FileField.

    I did not know about the “default_storage.delete” wrapper though, which is nice. I will update my code to use it.

    There’s also the reverse approach using a management command:

    https://github.com/django-extensions/django-extensions/blob/master/django_extensions/management/commands/unreferenced_files.py

    I did not test it yet thought..

    Cheers!

  2. Chander says:

    I’m not sure why you don’t use the FieldFiled object’s storage class – using the default storage might not match the storage object that’s in use by the FileField object.

    Better off saying (for example):

    field.storage.delete(field.path)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>