Package: django-ok-images
WebP sizers and filters fordjango-versatileimagefield. Custom image field with direct access to created images through readable names and model mixin to inherit. Helper utils to delete created images, clear cache and warm images.InstallationInstall with pip:$pipinstalldjango-ok-imagesdjango-versatileimagefieldUpdate INSTALLED_APPS:INSTALLED_APPS=[...'versatileimagefield',...]Available settingsIMAGE_ALLOWED_EXTENSIONS- Extensions forOptimizedImageField’sFileExtensionValidator.IMAGE_MAX_FILE_SIZE- Max file size of uploaded images in megabytes. Default to10.IMAGE_OPTIMIZE_QUALITY- Quality to optimize an uploaded image.IMAGE_CREATE_ON_DEMAND- Custom value fordjango-versatileimagefieldcreate_images_on_demandsetting.IMAGE_PLACEHOLDER_PATH- Default placeholder path fordjango-versatileimagefield.IMAGE_RGBA_CHANGE_BACKGROUND- Changes background of RGBA images to white color.IMAGE_LOSSLESS- Image lossless configuration. Default toFalse.How to enable image optimization through TinyPNG:TINYPNG_API_KEY_FUNCTION- Path to function, which returns TinyPNG api key.TINYPNG_API_KEY- TinyPNG api key.How to useWebP sizers and filter:Add next file in any app to register sizers and filters (more about sizers and filters):# versatileimagefield.pyfromok_images.contrib.versatileimagefield.versatileimagefieldimport*Fields:There is anOptimizedImageField, inherited fromVersatileImageField.Example of usage:Add next settings (more about rendition key sets):# settings.pyVERSATILEIMAGEFIELD_RENDITION_KEY_SETS={'product':[('full_size','url'),('desktop','crop__460x430'),('catalog_preview','crop__180x180'),# webp('desktop_webp','crop_webp__460x430'),('catalog_preview_webp','crop_webp__180x180'),],}Define a model like this:# models.pyfromok_images.fieldsimportOptimizedImageFieldclassProduct(models.Model):image_sizes='product'# could be set as a global rendition key set for an each image fieldimage=OptimizedImageField(_('Image'),ppoi_field='ppoi',blank=True,null=True,# Optional keyword arguments with default valuesimage_sizes_serializer=VersatileImageFieldSerializer,# from versatileimagefield.serializers import VersatileImageFieldSerializerimage_sizes='product',# some of keys, defined in VERSATILEIMAGEFIELD_RENDITION_KEY_SETS settingcreate_on_demand=True,# enables or disables on-demand image creation)ppoi=PPOIField(verbose_name=_('PPOI'))Ifimage_sizesis not defined, uses next default rendition key set:IMAGE_DEFAULT_RENDITION_KEY_SET=[('full_size','url'),]How to access generated previews:product.image.full_sizeproduct.image.catalog_previewproduct.image.desktop_webpUtils:delete_all_created_images- delete all created images (can be skipped withdelete_imagesargument) and clear cache for passed models.warm_images- creates all sized images for a given instance or queryset with passed rendition key set.# anywhere.pyfromok_images.utilsimportdelete_all_created_images,warm_imagesdelete_all_created_images(Product,delete_images=False)warm_images(product,'product')# `rendition_key_set` could be taken from field's or model's attrbiute `image_sizes`, otherwise uses default key setwarm_images(Product.objects.all())Async image warming:tasks.py:fromok_images.utilsimportwarm_images@app.taskdefimages_warmer_task(product_pk:int):fromstore.modelsimportProductproduct=Product.objects.get(pk=product_pk)warm_images(instance_or_queryset=product,image_attr='image')models.py:from.tasksimportimages_warmer_taskdefimages_warmer(product):images_warmer_task.delay(product.pk)classProduct(models.Model):image_sizes='product'image=OptimizedImageField(_('Image'),ppoi_field='ppoi',blank=True,null=True,images_warmer=images_warmer)