Cleanup cached thumbnails
philippeluickx opened this issue · 18 comments
Not sure if this should be in scope, but what would be the best approach to order generated thumbnails?
I am using https://github.com/SmileyChris/easy-thumbnails
Thanks for a nice library!
I did not use easy-thumbnails, but as I see ThumbnailerFieldFile deletes thumbnails and cache within delete method. So I guess all should work.
class ThumbnailerFieldFile(FieldFile, Thumbnailer):
...
def delete(self, *args, **kwargs):
"""
Delete the image, along with any generated thumbnails.
"""
source_cache = self.get_source_cache()
# First, delete any related thumbnails.
self.delete_thumbnails(source_cache)
# Next, delete the source image.
super(ThumbnailerFieldFile, self).delete(*args, **kwargs)
# Finally, delete the source cache entry.
if source_cache:
source_cache.delete()
...
I get it, django-cleanup does not invoke delete method on filefield.
Alright, I will fix it.
Now it should work, please check code from master branch.
Hey!
Thanks for the swift reply, I am impressed!
I tried it out and not there for me yet. I was not super clear in my issue either, so more info:
In my setup, easy-thumbnails generates new images with a different naming. They are in the same location as the original file.
E.g.:
Original file:
WP_20150217_14_27_34_Pro.jpg
Cached files:
WP_20150217_14_27_34_Pro.jpg.300x300_q85_detail_upscale.jpg
WP_20150217_14_27_34_Pro.jpg.900x600_q85_box-128,0,1504,918_crop_detail_upscale.jpg
WP_20150217_14_27_34_Pro.jpg.900x600_q85_box-131,0,1510,918_crop_detail_upscale.jpg
After deleting the file through my interface, the original file is gone, but not the cached files.
Try now, easy-thumbnails is test covered.
Hmm, just trying it out on my server and now even the original file does not get deleted.
I am using django-storages for saving media files to S3, but at least previously the original file was deleted, so guessing that S3 should not be the issue here.
Anything I can do to help?
You could show how you use easy-thumbnails, or you can open tests and try to repeat you case.
Had a quick look at the code and on first sight I think the cached files are not deleted because they are not linked to any model directly. With easy-thumbnails, the model is saved in a thumbnail model, which does not have a FileField
https://github.com/SmileyChris/easy-thumbnails/blob/master/easy_thumbnails/models.py
class File(models.Model):
storage_hash = models.CharField(max_length=40, db_index=True)
name = models.CharField(max_length=255, db_index=True)
modified = models.DateTimeField(default=timezone.now)
objects = FileManager()
class Meta:
abstract = True
unique_together = (('storage_hash', 'name'),)
def __unicode__(self):
return self.name
class Source(File):
pass
class Thumbnail(File):
source = models.ForeignKey(Source, related_name='thumbnails')
class Meta:
unique_together = (('storage_hash', 'name', 'source'),)
For reference, my implementation looks as follows:
class Picture(TimeStampedModel):
"""
A generic class for pictures.
"""
class Meta:
abstract = True
def __unicode__(self):
return self.caption
@property
def get_absolute_image_url(self):
return "{0}{1}".format(settings.MEDIA_URL, self.original_image.url)
original_image = models.ImageField(
'Image',
upload_to='pictures/%Y/%m/%d',
help_text="Optimal resolution 900x600"
)
title = models.CharField(
max_length=50,
blank=True,
)
caption = models.TextField(
blank=True,
validators=[MaxLengthValidator(140)],
)
class CachedPicture(Picture):
"""
A generic class for pictures.
"""
class Meta:
abstract = True
# Using ImageKit to define resolution
# for image to be used in carousel and as thumbnail.
big_image = ImageSpecField(
[SmartResize(900, 600)],
source='original_image',
format='JPEG',
options={'quality': 75}
)
medium_image = ImageSpecField(
[SmartResize(450, 300)],
source='original_image',
format='JPEG',
options={'quality': 75}
)
Don't see where do you use easy-thumbnail in your code. There is no ThumbnailerImageField or easy_thumbnails imports;
ThumbnailerImageField is based on ImageField which based on FileField. https://github.com/SmileyChris/easy-thumbnails/blob/master/easy_thumbnails/fields.py#L32
As I see you use ImageSpecField(from ImageKit) which is not based on FileField. So this is why django-cleanup does not work in your case.
You are absolutely right, sorry for that!
In this case: any plans for supporting imagekit?
Do you know how to delete these files? There are seems no delete method on ImageSpecField.
Seems like an open issue:
matthewwithanm/django-imagekit#229
I think it is responsibility ImageKit contributors to implement delete method at first.
big_image = ImageSpecField(
[SmartResize(900, 600)],
source='original_image',
format='JPEG',
options={'quality': 75}
)
If you use just such simple image processing, you could try django-resized
Or you could use sorl-thumbnail or easy-thumbnail.
Thanks for the info, will have a look to that!
I will close this issue for now, let's see if imagekit manages to have a delete function somewhere in the future.
I am having the same problem as the original poster - but I am only using django's ImageField and easy-thumbnails. I put together a repo that demonstrates what I am seeing in my larger project. Many of my other problems have been misconfiguration or not recognizing the relevance of something in the docs. Can you tell me what I am missing?
There are tests for easy-thumbnail, all should work, you could look at testapp
https://github.com/un1t/django-cleanup/tree/master/django_cleanup/testapp
For anyone else having the same problem, the aforementioned tests showed me that to get easy--thumbnails and django-cleanup to work nicely together, you need to define your image field as easy_thumbnails.fields.ThumbnailerImageField rather than Django's default ImageField. Once you do that, both work perfectly.
Thanks @un1t for this app which provides the missing behavior I expected from django itself.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.