During development, VersatileImageField
's on-demand image creation <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.
To turn off on-demand image creation just set the 'create_images_on_demand'
key of the VERSATILEIMAGEFIELD_SETTINGS
setting to False
(docs <versatileimagefield-settings>
). Now your VersatileImageField
fields will return URLs to images without first checking to see if they've actually been created yet.
Note
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 VERSATILEIMAGEFIELD_SETTINGS['create_images_on_demand']
to False
bypasses this entirely making VersatileImageField
perform even faster (docs <versatileimagefield-settings>
).
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 <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.
Note
The above example would create a set of images (as dictated by the 'person_headshot'
Rendition Key Set <reusing-rendition-key-sets>
) for the headshot
field of each Person
instance. rendition_key_set
also accepts a valid Rendition Key Set <rendition-key-sets>
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
... )
Note
Setting 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%)
Note
The image_attr
argument can be dot-notated in order to follow ForeignKey
and OneToOneField
relationships. Example: 'related_model.headshot'
.
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()