mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-29 17:36:49 +01:00
de28bca258
Co-authored-by: Thibaud Colas <thibaudcolas@gmail.com>
138 lines
4.8 KiB
Markdown
138 lines
4.8 KiB
Markdown
(image_renditions)=
|
|
|
|
# Generating renditions in Python
|
|
|
|
Rendered versions of original images generated by the Wagtail `{% image %}` template tag are called "renditions",
|
|
and are stored as new image files in the site's `[media]/images` directory on the first invocation.
|
|
|
|
Image renditions can also be generated dynamically from Python via the native `get_rendition()` method, for example:
|
|
|
|
```python
|
|
newimage = myimage.get_rendition('fill-300x150|jpegquality-60')
|
|
```
|
|
|
|
If `myimage` had a filename of `foo.jpg`, a new rendition of the image file called
|
|
`foo.fill-300x150.jpegquality-60.jpg` would be generated and saved into the site's `[media]/images` directory.
|
|
Argument options are identical to the `{% image %}` template tag's filter spec, and should be separated with `|`.
|
|
|
|
The generated `Rendition` object will have properties specific to that version of the image, such as
|
|
`url`, `width` and `height`. Hence, something like this could be used in an API generator, for example:
|
|
|
|
```python
|
|
url = myimage.get_rendition('fill-300x186|jpegquality-60').url
|
|
```
|
|
|
|
Properties belonging to the original image from which the generated Rendition was created, such as `title`, can
|
|
be accessed through the Rendition's `image` property:
|
|
|
|
```python
|
|
>>> newimage.image.title
|
|
'Blue Sky'
|
|
>>> newimage.image.is_landscape()
|
|
True
|
|
```
|
|
|
|
See also: [](image_tag)
|
|
|
|
(prefetching_image_renditions)=
|
|
|
|
## Prefetching image renditions
|
|
|
|
When using a queryset to render a list of images or objects with images, you can prefetch the renditions needed with a single additional query. For long lists of items, or where multiple renditions are used for each item, this can provide a significant boost to performance.
|
|
|
|
```{versionadded} 4.0
|
|
The `prefetch_renditions` method is only applicable in Wagtail versions 4.0 and above.
|
|
```
|
|
|
|
### Image QuerySets
|
|
|
|
When working with an Image QuerySet, you can make use of Wagtail's built-in `prefetch_renditions` queryset method to prefetch the renditions needed.
|
|
|
|
For example, say you were rendering a list of all the images uploaded by a user:
|
|
|
|
```python
|
|
def get_images_uploaded_by_user(user):
|
|
return ImageModel.objects.filter(uploaded_by_user=user)
|
|
```
|
|
|
|
The above can be modified slightly to prefetch the renditions of the images returned:
|
|
|
|
```python
|
|
def get_images_uploaded_by_user(user)::
|
|
return ImageModel.objects.filter(uploaded_by_user=user).prefetch_renditions()
|
|
```
|
|
|
|
The above will prefetch all renditions even if we may not need them.
|
|
|
|
If images in your project tend to have very large numbers of renditions, and you know in advance the ones you need, you might want to consider specifying a set of filters to the `prefetch_renditions` method and only select the renditions you need for rendering. For example:
|
|
|
|
```python
|
|
def get_images_uploaded_by_user(user):
|
|
# Only specify the renditions required for rendering
|
|
return ImageModel.objects.filter(uploaded_by_user=user).prefetch_renditions(
|
|
"fill-700x586", "min-600x400", "max-940x680"
|
|
)
|
|
```
|
|
|
|
### Non Image Querysets
|
|
|
|
If you're working with a non Image Model, you can make use of Django's built-in `prefetch_related()` queryset method to prefetch renditions.
|
|
|
|
For example, say you were rendering a list of events (with thumbnail images for each). Your code might look something like this:
|
|
|
|
```python
|
|
def get_events():
|
|
return EventPage.objects.live().select_related("listing_image")
|
|
```
|
|
|
|
The above can be modified slightly to prefetch the renditions for listing images:
|
|
|
|
```python
|
|
def get_events():
|
|
return EventPage.objects.live().select_related("listing_image").prefetch_related("listing_image__renditions")
|
|
```
|
|
|
|
If you know in advance the renditions you'll need, you can filter the renditions queryset to use:
|
|
|
|
```python
|
|
from django.db.models import Prefetch
|
|
from wagtail.images import get_image_model
|
|
|
|
|
|
def get_events():
|
|
Image = get_image_model()
|
|
filters = ["fill-300x186", "fill-600x400", "fill-940x680"]
|
|
|
|
# `Prefetch` is used to fetch only the required renditions
|
|
prefetch_images_and_renditions = Prefetch(
|
|
"listing_image",
|
|
queryset=Image.objects.prefetch_renditions(*filters)
|
|
)
|
|
return EventPage.objects.live().prefetch_related(prefetch_images_and_renditions)
|
|
```
|
|
|
|
(image_rendition_methods)=
|
|
|
|
## Model methods involved in rendition generation
|
|
|
|
```{versionadded} 3.0
|
|
The following method references are only applicable to Wagtail versions 3.0 and above.
|
|
```
|
|
|
|
The following `AbstractImage` model methods are involved in finding and generating renditions. If using a custom image model, you can customise the behaviour of either of these methods by overriding them on your model:
|
|
|
|
```{eval-rst}
|
|
.. automodule:: wagtail.images.models
|
|
|
|
.. class:: AbstractImage
|
|
:noindex:
|
|
|
|
.. automethod:: get_rendition
|
|
|
|
.. automethod:: find_existing_rendition
|
|
|
|
.. automethod:: create_rendition
|
|
|
|
.. automethod:: generate_rendition_file
|
|
```
|