Can't delete FileField's file in post_delete
django, django-models
Solution
When you access a `FileField` attribute you get a `FieldFile` wrapper instance. Now guess what is the code of its `.delete` method... (ripped from django.db.models.fields.files )
def delete(self, save=True):
# Only close the file if it's already open, which we know by the
# presence of self._file
if hasattr(self, '_file'):
self.close()
del self.file
self.storage.delete(self.name)
self.name = None
setattr(self.instance, self.field.name, self.name)
# Delete the filesize cache
if hasattr(self, '_size'):
del self._size
self._committed = False
if save:
self.instance.save()
So you were correct :)
If I'm reading it correctly, you could now hook it up again to the `post_delete` signal and pass `save=False` on the delete method and it should work.
And yes, I just looked it up because of your question.
Problem
I have a model with a `FileField`: ``` class FileModel(models.Model): name = models.CharField(max_length=100) description = models.CharField(max_length=200) file = models.FileField(upload_to='myfiles') ``` When you delete a model instance with a `FileField`, django doesn't automatically delete the underlying file from the filesystem, so I set up a signal to delete the underlying file on `post_delete`: ``` def on_delete(sender, instance, **kwargs): instance.file.delete() models.signals.post_delete.connect(on_delete, sender=FileModel) ``` The problem is, when I delete a `FileModel` object (let's say from the django admin page) it deletes the file from the filesystem, but doesn't delete the model. If I delete it again, it deletes the model but then raises an exception when it tries to delete the file from the filesystem, because the file doesn't exist. When I change the file deletion to occur on `pre_delete` instead of `post_delete` it behaves as it should. The only thing that I can think of that would cause this behavior is if deleting the file from the `FileField` automatically saves the model, which would cause it to be recreated in `post_delete`. So my question is: why does calling a `FileField`'s delete method in `post_delete` prevent the model from being deleted?