4

So I have the following model.

class StoreSegments01(models.Model):
    segment = models.FileField(upload_to=content_file_name)
    segmentID = models.TextField(max_length=100, default=11)

class StoreSegments01Form(forms.ModelForm):
    class Meta:
    model = StoreSegments01
    fields = ['segment', 'segmentID']

def content_file_name(instance, filename):
    return '{0}'.format(instance.segmentID)

I want to provide a way for the users to delete their files. In manage.py shell I try the following:

obj = StoreSegments01.objects.get(segmentID='239fd363-562a-41b3-a915-b7a84cc4a172')
>>> obj.delete()

It deletes the record related to the specified segmentID, but the file associated with the ID is still there. I tried the same with queryset, still the file is not deleted.

What am I missing here?

Amir Afianian
  • 2,679
  • 4
  • 22
  • 46
  • Possible duplicate of [How do I get Django Admin to delete files when I remove an object from the database/model?](http://stackoverflow.com/questions/5372934/how-do-i-get-django-admin-to-delete-files-when-i-remove-an-object-from-the-datab) – Variant Jan 30 '16 at 16:34
  • @Variant Do I have to go with signals? – Amir Afianian Jan 30 '16 at 16:48
  • Or just install `pip install django-cleanup` as one of the answers mention – Ramast Jan 30 '16 at 16:51

1 Answers1

4

Here's an alternative to using signals: override the delete method of your model.

Example:

class StoreSegments01(models.Model):
    segment = models.FileField(upload_to=content_file_name)
    segmentID = models.TextField(max_length=100, default=11)

    def delete(self, *args, **kwargs):
        # first, delete the file
        self.segment.delete(save=False)

        # now, delete the object
        super(StoreSegments01, self).delete(*args, **kwargs)

For Python 3, call super like this: super().delete(*args, **kwargs)

Heads up! : This works if you delete individual objects. But if you delete objects in bulk, the associated files aren't deleted. Because deleting a single object calls model.delete() method but deleting in bulk calls queryset.delete() method. Thanks to Håken Lid who pointed this out in a comment below.

Community
  • 1
  • 1
xyres
  • 20,487
  • 3
  • 56
  • 85
  • 1
    You can use `django.db.models.signals.pre_delete` instead of overriding the `delete()` method. Signals will listen to both model.delete() and queryset.delete(). Docs: https://docs.djangoproject.com/en/1.9/topics/signals/ – Håken Lid Jan 30 '16 at 19:53
  • @HåkenLid Hey, thanks. Now I understand why files weren't deleting using bulk delete. – xyres Jan 30 '16 at 20:02
  • You made my day, thany you a lot, it was very simple :D `self.segment.delete(save=False)` and also `super(self.__class__, self).delete(*args, **kwargs)` – Tarek Kalaji Nov 10 '17 at 13:55