VersatileImageField‘s on-demand image creation enables you to quickly iterate but, once your application is deployed into production, this convenience adds a small bit of overhead that you’ll probably want to turn off.
Turning off on-demand image creation¶
To turn off on-demand image creation just set the
'create_images_on_demand' key of the
VERSATILEIMAGEFIELD_SETTINGS setting to
False (docs). Now your
VersatileImageField fields will return URLs to images without first checking to see if they’ve actually been created yet.
Once an image has been created by a
VersatileImageField, a reference to it is stored in the cache which makes for speedy subsequent retrievals. Setting
False bypasses this entirely making
VersatileImageField perform even faster (docs).
Ensuring images are created¶
This boost in performance is great but now you’ll need to ensure that the images your application links-to actually exist. Luckily,
VersatileImageFieldWarmer will help you do just that. Here’s an example in the Python shell using the example model from the Django REST Framework serialization example:
>>> from myproject.person.models import Person >>> from versatileimagefield.image_warmer import VersatileImageFieldWarmer >>> person_img_warmer = VersatileImageFieldWarmer( ... instance_or_queryset=Person.objects.all(), ... rendition_key_set='person_headshot', ... image_attr='headshot', ... verbose=True ... ) >>> num_created, failed_to_create = person_img_warmer.warm()
num_created will be an integer of how many images were successfully created and
failed_to_create will be a list of paths to images (on the field’s storage class) that could not be created (due to a PIL/Pillow error, for example).
This technique is useful if you’ve recently converted your project’s
models.ImageField fields to use
VersatileImageField or if you want to ‘pre warm’ images as part of a Fabric script.
The above example would create a set of images (as dictated by the
'person_headshot' Rendition Key Set) for the
headshot field of each
rendition_key_set also accepts a valid Rendition Key Set directly:
>>> person_img_warmer = VersatileImageFieldWarmer( ... instance_or_queryset=Person.objects.all(), ... rendition_key_set=[ ... ('large_horiz_crop', '1200x600'), ... ('large_vert_crop', '600x1200'), ... ], ... image_attr='headshot', ... verbose=True ... )
verbose=True when instantiating a
VersatileImageFieldWarmer will display a yum-style progress bar showing the image warming progress:
>>> num_created, failed_to_create = person_img_warmer.warm() [###########----------------------------------------] 20/100 (20%)
image_attr argument can be dot-notated in order to follow
OneToOneField relationships. Example:
Auto-creating sets of images on
You also might want to create new images immediately after model instances are saved. Here’s how we’d do it with our example model (see highlighted lines below):
# myproject/person/models.py from django.db import models from django.dispatch import receiver from versatileimagefield.fields import VersatileImageField, PPOIField from versatileimagefield.image_warmer import VersatileImageFieldWarmer class Person(models.Model): """Represents a person.""" name_first = models.CharField('First Name', max_length=80) name_last = models.CharField('Last Name', max_length=100) headshot = VersatileImageField( 'Headshot', upload_to='headshots/', ppoi_field='headshot_ppoi' ) headshot_ppoi = PPOIField() class Meta: verbose_name = 'Person' verbose_name_plural = 'People' @receiver(models.signals.post_save, sender=Person) def warm_Person_headshot_images(sender, instance, **kwargs): """Ensures Person head shots are created post-save""" person_img_warmer = VersatileImageFieldWarmer( instance_or_queryset=instance, rendition_key_set='person_headshot', image_attr='headshot' ) num_created, failed_to_create = person_img_warmer.warm()