# HG changeset patch # User cavaliet # Date 1372930281 -7200 # Node ID f0883894f38645bc370824bdf754920d26be4e5b # Parent 2c3ceb119f0c5b45678fefa9f042b901e6b5c646 queries optimisation first step diff -r 2c3ceb119f0c -r f0883894f386 src/egonomy/utils/queries.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/egonomy/utils/queries.py Thu Jul 04 11:31:21 2013 +0200 @@ -0,0 +1,44 @@ +''' +Cache the generic relation field of all the objects +in the queryset, using larger bulk queries ahead of time. + +Improved from original by Daniel Roseman: +http://blog.roseman.org.uk/2010/02/22/django-patterns-part-4-forwards-generic-relations/ + +Adapted for egonomy project by Thibaut Cavalie +''' +from django.contrib.contenttypes.models import ContentType +from egonomy.models import Image, Fragment + +import logging +logger = logging.getLogger(__name__) + +def cache_generics(queryset): + generics = {} + for item in queryset: + if item.object_id is not None: + generics.setdefault(item.content_type_id, set()).add(item.object_id) + + content_types = ContentType.objects.in_bulk(generics.keys()) + relations = {} + for ct, fk_list in generics.iteritems(): + ct_model = content_types[ct].model_class() + # In our case relations[ct] = ct_model.objects.in_bulk(list(fk_list)) + # is not enough because we need select_related for both images and fragments + if content_types[ct] == ContentType.objects.get_for_model(Image): + relations[ct] = ct_model.objects.select_related('info', 'metadata').in_bulk(list(fk_list)) + elif content_types[ct] == ContentType.objects.get_for_model(Fragment): + relations[ct] = ct_model.objects.select_related('image', 'image__info', 'image__metadata','author').in_bulk(list(fk_list)) + else: + relations[ct] = ct_model.objects.in_bulk(list(fk_list)) + + for item in queryset: + try: + try: + item.object_id = int(item.object_id) + except: + pass + cached_val = relations[item.content_type_id][item.object_id] + except KeyError: + cached_val = None + setattr(item, '_content_object_cache', cached_val) \ No newline at end of file diff -r 2c3ceb119f0c -r f0883894f386 src/egonomy/views.py --- a/src/egonomy/views.py Wed Jul 03 10:15:01 2013 +0200 +++ b/src/egonomy/views.py Thu Jul 04 11:31:21 2013 +0200 @@ -15,6 +15,7 @@ from egonomy.search_indexes import QueryParser from egonomy.search_indexes.paginator import SearchPaginator from egonomy.search_indexes.query import ModelRelatedSearchQuerySet +from egonomy.utils.queries import cache_generics from haystack.query import RelatedSearchQuerySet from sorl.thumbnail import default, get_thumbnail from sorl.thumbnail.images import ImageFile @@ -562,6 +563,7 @@ if display!="slideshow": # Avoid useless database query. The query will be done by embed_slideshow view items = CollectionItem.objects.filter(collection=col).select_related('author', 'content_type', 'object_id', 'content_object').order_by("order") + cache_generics(items) return render_to_response("egonomy_view_collection.html", {'col':col, 'items':items, 'display':display, @@ -594,6 +596,7 @@ col = get_object_or_404(Collection.objects.select_related('author'), pk=collection_pk) items = CollectionItem.objects.filter(collection=col).select_related('author', 'content_type', 'object_id', 'content_object').order_by("order") + cache_generics(items) return render_to_response("egonomy_embed_slideshow.html", {'col':col, 'items':items},