In Django, if you have a ImageFile in a model, deleting will remove the associated file from disk as well as removing the record from the database.
Shouldn't replacing an image also remove the unneeded file from disk? Instead, I see that it keeps the original and adds the replacement.
Now deleting the object won't delete the original file only the replacement.
Are there any good strategies to doing this? I don't want to have a bunch of orphan files if my users replace their images frequently.
In the olden days,
FileField
was eager to clean up orphaned files. But that changed in Django 1.2:The best strategy I've found is to make a custom save method in the model:
And beware, as with the updating which doesn't delete the back end file, deleting an instance model (here Photo) will not delete the back-end file, not in Django 1.3 anyway, you'll have to add more custom code to do that (or regularly do some dirty cron job).
Finally test all your update/delete cases with your ForeignKey, ManytoMany and others relations to check if the back-end files are correctly deleted. Believe only what you test.
The code in the following working example will, upon uploading an image in an ImageField, detect if a file with the same name exists, and in that case, delete that file before storing the new one.
It could easily be modified so that it deletes the old file regardless of the filename. But that's not what I wanted in my project.
Add the following class:
And use it with ImageField like so:
Here is a code that can work with or without
upload_to=...
orblank=True
, and when the submitted file has the same name as the old one.(py3 syntax, tested on Django 1.7)
Remember that this kind of solution is only applicable if you are in a non transactional context (no rollback, because the file is definitively lost)
If you don't use transactions or you don't afraid of loosing files on transaction rollback, you can use django-cleanup
I used a simple method with
popen
, so when i save myInfo
model i delete the former file before linking to the new: