Search code examples
djangodynamicpathimagekitdjango-imagekit

Django imagekit and dynamic paths


I'm using imagekit provided at: imagekit

So, I've defined two class model:

class Photo(models.Model):
    #photo_wrapper = models.ForeignKey(PhotoWrapper, blank=True, null=True)
    original_image = models.ImageField(upload_to='static/photos')
    thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
            resize.Crop(50, 50)], image_field='original_image',
            format='JPEG', quality=90)
    num_views = models.PositiveIntegerField(editable=False, default=0)

    class IKOptions:
        # This inner class is where we define the ImageKit options for the model
        spec_module = 'myspecs.specs'
        cache_dir = 'static/photos'
        image_field = 'original_image'
        save_count_as = 'num_views'

class Country(models.Model):       
    country_name = models.CharField(max_length=250)        
    country_photo = models.ForeignKey(Photo, blank=True, null=True)

    def __unicode__(self):
            return '%s' % self.country_name 

The problem is that each photo is created in the "static/photos" path. My intent is to save the image and the thumbnail with a dynamic path, based on the country name..

For example, for the country "Argentina", the dynamic path will be "static/photos/Argentina/"

How can I accomplish that?


Solution

  • It looks like you're mixing two different versions of ImageKit. The newer versions (1.0+) no longer use the inner IKOptions class, so all of that is being ignored. (The save_count_as functionality was also removed.)

    If you want to control the cache filename, the ImageSpec constructor accepts a cache_to kwarg which—like ImageField's upload_to—can be a callable. Here's the current documentation for cache_to:

    Specifies the filename to use when saving the image
    cache file. This is modeled after ImageField's ``upload_to`` and
    can be either a string (that specifies a directory) or a
    callable (that returns a filepath). Callable values should
    accept the following arguments:
    
        - instance -- The model instance this spec belongs to
        - path -- The path of the original image
        - specname -- the property name that the spec is bound to on
            the model instance
        - extension -- A recommended extension. If the format of the
            spec is set explicitly, this suggestion will be
            based on that format. if not, the extension of the
            original file will be passed. You do not have to use
            this extension, it's only a recommendation.
    

    So you'll just have to create a function that accepts those arguments and returns the path you want, and use that in your model like so:

    class Photo(models.Model):
        thumbnail = ImageSpec(..., cache_to=my_cache_to_function)