|
@@ -38,11 +38,45 @@ See also: [](image_tag)
|
|
|
|
|
|
## Prefetching image renditions
|
|
|
|
|
|
-```{versionadded} 3.0
|
|
|
-This following guidance is only applicable in Wagtail versions 3.0 and above.
|
|
|
+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 certain 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()
|
|
|
```
|
|
|
|
|
|
-When using a queryset to render a list of objects with images, you can make use of Django's built-in `prefetch_related()` queryset method to prefetch the renditions needed for rendering 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.
|
|
|
+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:
|
|
|
|
|
@@ -58,7 +92,8 @@ def get_events():
|
|
|
return EventPage.objects.live().select_related("listing_image").prefetch_related("listing_image__renditions")
|
|
|
```
|
|
|
|
|
|
-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 using a `Prefetch` object to select only the renditions you need for rendering. For example:
|
|
|
+
|
|
|
+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
|
|
@@ -66,15 +101,15 @@ from wagtail.images import get_image_model
|
|
|
|
|
|
|
|
|
def get_events():
|
|
|
- # These are the renditions required for rendering
|
|
|
- renditions_queryset = get_image_model().get_rendition_model().objects.filter(
|
|
|
- filter_spec__in=["fill-300x186", "fill-600x400", "fill-940x680"]
|
|
|
- )
|
|
|
-
|
|
|
+ Image = get_image_model()
|
|
|
+ filters = ["fill-300x186", "fill-600x400", "fill-940x680"]
|
|
|
+
|
|
|
# `Prefetch` is used to fetch only the required renditions
|
|
|
- return EventPage.objects.live().select_related("listing_image").prefetch_related(
|
|
|
- Prefetch("listing_image__renditions", queryset=renditions_queryset)
|
|
|
+ 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)=
|