django-ok-images 0.1.8
django-ok-images allows to generate WebP images using django-versatileimagefield.
License: MIT
Keywords: python,images,image-models,django,webp,django-versatileimagefield

===============================
django-ok-images |PyPI version|
===============================

|Build Status| |Code Health| |Python Versions| |PyPI downloads| |license| |Project Status|

WebP sizers and filters for `django-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.

Installation
============

Install with pip:

.. code:: shell

    $ pip install django-ok-images django-versatileimagefield

Update INSTALLED_APPS:

.. code:: python

    INSTALLED_APPS = [
        ...
        'versatileimagefield',
        ...
    ]



Available settings
==================

``IMAGE_ALLOWED_EXTENSIONS`` - Extensions for `OptimizedImageField`'s `FileExtensionValidator`.

``IMAGE_MAX_FILE_SIZE`` - Max file size of uploaded images in megabytes. Default to `10`.

``IMAGE_OPTIMIZE_QUALITY`` - Quality to optimize an uploaded image.

``IMAGE_CREATE_ON_DEMAND`` - Custom value for `django-versatileimagefield`_ `create_images_on_demand` setting.

``IMAGE_PLACEHOLDER_PATH`` - Default placeholder path for `django-versatileimagefield`_.

``IMAGE_RGBA_CHANGE_BACKGROUND`` - Changes background of RGBA images to white color.

``IMAGE_LOSSLESS`` - Image lossless configuration. Default to `False`.

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 use
==========

WebP sizers and filter:
-----------------------

Add next file in any app to register sizers and filters (`more about sizers and filters <https://django-versatileimagefield.readthedocs.io/en/latest/writing_custom_sizers_and_filters.html#registering-sizers-and-filters>`_):

.. code:: python

    # versatileimagefield.py

    from ok_images.contrib.versatileimagefield.versatileimagefield import *


Fields:
-------

There is an ``OptimizedImageField``, inherited from `VersatileImageField <https://django-versatileimagefield.readthedocs.io/en/latest/model_integration.html#model-integration>`_.

Example of usage:

Add next settings (`more about rendition key sets <https://django-versatileimagefield.readthedocs.io/en/latest/drf_integration.html#reusing-rendition-key-sets>`_):

.. code:: python

    # settings.py

    VERSATILEIMAGEFIELD_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:

.. code:: python

    # models.py
    from ok_images.fields import OptimizedImageField
    

    class Product(models.Model):
        image_sizes = 'product'  # could be set as a global rendition key set for an each image field

        image = OptimizedImageField(
            _('Image'),
            ppoi_field='ppoi',
            blank=True,
            null=True,
            # Optional keyword arguments with default values
            image_sizes_serializer=VersatileImageFieldSerializer,  # from versatileimagefield.serializers import VersatileImageFieldSerializer
            image_sizes='product',  # some of keys, defined in VERSATILEIMAGEFIELD_RENDITION_KEY_SETS setting
            create_on_demand=True,  # enables or disables on-demand image creation
        )
        ppoi = PPOIField(
            verbose_name=_('PPOI')
        )

If ``image_sizes`` is not defined, uses next default rendition key set:

.. code:: python

    IMAGE_DEFAULT_RENDITION_KEY_SET = [
        ('full_size', 'url'),
    ]

How to access generated previews:

.. code:: python

    product.image.full_size
    product.image.catalog_preview
    product.image.desktop_webp


Utils:
------

``delete_all_created_images`` - delete all created images (can be skipped with ``delete_images`` argument) and clear cache for passed models.

``warm_images`` - creates all sized images for a given instance or queryset with passed rendition key set.

.. code:: python
    
    # anywhere.py
    from ok_images.utils import delete_all_created_images, warm_images
		
    	
    delete_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 set
    warm_images(Product.objects.all())


Async image warming:
--------------------

`tasks.py`:

.. code:: python

    from ok_images.utils import warm_images

    @app.task
    def images_warmer_task(product_pk: int):
        from store.models import Product
        product = Product.objects.get(pk=product_pk)
        warm_images(
            instance_or_queryset=product,
            image_attr='image'
        )


`models.py`:

.. code:: python
   
    from .tasks import images_warmer_task
    	
    	
    def images_warmer(product):
        images_warmer_task.delay(product.pk)
	
		
    class Product(models.Model):
        image_sizes = 'product'

        image = OptimizedImageField(
            _('Image'),
            ppoi_field='ppoi',
            blank=True,
            null=True,
            images_warmer=images_warmer
        )


.. |PyPI version| image:: https://badge.fury.io/py/django-ok-images.svg
   :target: https://badge.fury.io/py/django-ok-images
.. |Build Status| image:: https://github.com/LowerDeez/ok-images/workflows/Upload%20Python%20Package/badge.svg
   :target: https://github.com/LowerDeez/ok-images/
   :alt: Build status
.. |Code Health| image:: https://api.codacy.com/project/badge/Grade/e5078569e40d428283d17efa0ebf9d19
   :target: https://www.codacy.com/app/LowerDeez/ok-images
   :alt: Code health
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/django-ok-images.svg
   :target: https://pypi.org/project/django-ok-images/
   :alt: Python versions
.. |license| image:: https://img.shields.io/pypi/l/django-ok-images.svg
   :alt: Software license
   :target: https://github.com/LowerDeez/ok-images/blob/master/LICENSE
.. |PyPI downloads| image:: https://img.shields.io/pypi/dm/django-ok-images.svg
   :alt: PyPI downloads
.. |Project Status| image:: https://img.shields.io/pypi/status/django-ok-images.svg
   :target: https://pypi.org/project/django-ok-images/
   :alt: Project Status

.. _django-versatileimagefield: https://github.com/respondcreate/django-versatileimagefield