Search code examples
pythondjangodjango-imagekit

Django Imagekit overwrite cachefile_name?


I'm trying to overwrite the cachefile_name property from the module django-imagekit.

Here is my code:

class Thumb150x150(ImageSpec):
    processors = [ResizeToFill(150, 150)]
    format = 'JPEG'
    options = {'quality': 90}

    @property
    def cachefile_name(self):
        # simplified for this example
        return "bla/blub/test.jpg"

register.generator('blablub:thumb_150x150', Thumb150x150)

class Avatar(models.Model):
avatar= ProcessedImageField(upload_to=upload_to,
                            processors=[ConvertToRGBA()],
                            format='JPEG',
                            options={'quality': 60})
avatar_thumb = ImageSpecField(source='avatar',
                              id='blablub:thumb_150x150')

It doesn't work at all.
When I debug (without my overwrite of cachefile_name), and look at the return value of cachefile_name, the result is a string like "CACHE/blablub/asdlkfjasd09fsaud0fj.jpg". Where is my mistake?

Any ideas?


Solution

  • Replicating the example as closely as I could, it worked fine. A couple of suggestions are:

    1) Make sure you are using the avatar_thumb in a view. The file "bla/blub/test.jpg" won't be generated until then.

    2) Check the configuration of your MEDIA_ROOT to make sure you know where "bla/blub/test.jpg" is expected to appear.

    Let me give an example of something similar I was working on. I wanted to give my thumbnails unique names that can be predicted from the original filename. Imagekit's default scheme names the thumbnails based on a hash, which I can't guess. Instead of this:

    media/12345.jpg
    media/CACHE/12345/abcde.jpg
    

    I wanted this:

    media/photos/original/12345.jpg
    media/photos/thumbs/12345.jpg
    

    Overriding IMAGEKIT_SPEC_CACHEFILE_NAMER didn't work because I didn't want all of my cached files to end up in the "thumbs" directory, just those generated from a specific field in a specific model.

    So I created this ImageSpec subclass and registered it:

    class ThumbnailSpec(ImageSpec):
        processors=[Thumbnail(200, 200, Anchor.CENTER, crop=True, upscale=False)]
        format='JPEG'
        options={'quality': 90}
    
        # put thumbnails into the "photos/thumbs" folder and
        # name them the same as the source file
        @property
        def cachefile_name(self):
            source_filename = getattr(self.source, 'name', None)
            s = "photos/thumbs/" + source_filename
            return s
    
    register.generator('myapp:thumbnail', ThumbnailSpec)
    

    And then used it in my model like this:

    # provide a unique name for each image file
    def get_file_path(instance, filename):
        ext = filename.split('.')[-1]
        return "%s.%s" % (uuid.uuid4(), ext.lower())
    
    # store the original images in the 'photos/original' directory
    photoStorage = FileSystemStorage(
        location=os.path.join(settings.MEDIA_ROOT, 'photos/original'),
        base_url='/photos/original')
    
    class Photo(models.Model):
        image = models.ImageField(storage=photoStorage, upload_to=get_file_path)
        thumb = ImageSpecField(
            source='image',
            id='myapp:thumbnail')