easy-thumbnails icon indicating copy to clipboard operation
easy-thumbnails copied to clipboard

Getting all your thumbnails at once from a list of objects

Open renegadeofunk opened this issue 11 years ago • 10 comments

I'm using the template version of thumbnail generation/display, but I noticed through profiling that I have ~100 DB queries on pages that use a lot of thumbnails (looping through each object with {% thumbnail blahblah %} ), and it's from doing every individual select from easy_thumbnails_source and easy_thumbnails_thumbnail.

I looked into selecting all thumbnails in bulk given a list of object ID's or something like that, but it doesn't seem possible. Could something like that be added, or am I missing an obvious way to accomplish it?

renegadeofunk avatar Jul 13 '13 23:07 renegadeofunk

Yes, I started napkin planning this feature but haven't implemented anything in code.

Having a way of bulk selecting certain aliases for a queryset would be great. If you want to have a first crack at it then go right ahead.

PS: you might want to try master, it may reduce some queries. I'll release as an official version soon, hopefully.

SmileyChris avatar Jul 15 '13 23:07 SmileyChris

Ok, that would be a good side project actually. Thanks.

renegadeofunk avatar Jul 15 '13 23:07 renegadeofunk

Any progress on this? Is there any way to use select_related() or prefetch_related() on a queryset to reduce the number of database lookups of thumbnails?

lsemel avatar Jan 03 '14 19:01 lsemel

Hi ... I'm also wondering has this beend moved from napkin stage. Can anything be done to help out/speed things regarding this.

chubz avatar Jun 23 '14 16:06 chubz

+1 to prior comments. I often end up with views with several hundred queries. I will definitely poke around and look at reducing query counts myself before I switch to sorl, but that's becoming a definite option.

Kobold avatar Jun 27 '14 00:06 Kobold

Another alternative is to introduce a memcached backed engine similar to django.contrib.sessions.backends.cached_db. While it doesn't necessarily reduce query counts, it will at least take the load off your main DB.

I've also been experimenting with a brand new library designed with pluggable metadata backend, remote storages and image post processing in mind. It's a young project and is definitely lacking in documentation, but I've been using it in production for a few months: https://github.com/ui/django-thumbnails

selwin avatar Jun 27 '14 02:06 selwin

Any news on this?

lsemel avatar Feb 17 '17 18:02 lsemel

Yeah, check out https://github.com/SmileyChris/easy-images

Its in a late alpha stage, feedback from usage in real world projects would be appreciated.

On Sat, 18 Feb 2017, 7:19 AM Lee Semel [email protected] wrote:

Any news on this?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/SmileyChris/easy-thumbnails/issues/245#issuecomment-280726659, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGtf1SuUg0fMxW8o16QfKjYgwKfEGsIks5rdeTNgaJpZM4A0D2G .

SmileyChris avatar Feb 17 '17 19:02 SmileyChris

If anybody is still using easy_thumbnails and needs this feature to avoid thousands of errant DB queries, it can be done by querying easy_thumbnails models directly. Generally not recommended but if unavoidable if you're in a situation similar to my own, with your thumbnailer being a bottleneck causing a view to take several seconds to load.

Something like this:

from django.conf import settings
from django.db.models import Subquery, OuterRef
from easy_thumbnails.models import ThumbnailDimensions

def annotate_queryset_with_thumbnails(queryset, thumbnail_size):
    width, height = thumbnail_size = settings.THUMBNAIL_ALIASES['my.Thumbnail.alias'][thumbnail_size]['size']
    size_name = f'_{thumbnail_size[0]}x{thumbnail_size[1]}.'  # Contains `_` prefix and `.` suffix to avoid false positives
    thumbnails_subquery = Subquery(
        Thumbnail.objects.filter(
            source__name=OuterRef('image'),  # Original image name should be exact match
            name__icontains=size_name,
            ).values('name')[:1]
    )
    return queryset.annotate(thumbnail=thumbnails_subquery)

This assumes that your ThumbnailerImageField is defined on your model with the field name image. You can change the OuterRef to be whatever your model uses.

Doing this bypasses all of the side-effects of the actual thumbnailer, primarily the actual generation of thumbnails when they don't exist. I recommend in your view or serializer or wherever that you fall back to the thumbnailer for the objects in your queryset that turn up null.

Checkroth avatar May 24 '21 07:05 Checkroth

@Checkroth, any other alternative to easy_thumbnails? I'm struggling with this with tons of nested serializers

MrRoiz avatar Dec 27 '23 01:12 MrRoiz