queries optimisation first step
authorcavaliet
Thu, 04 Jul 2013 11:31:21 +0200
changeset 217 f0883894f386
parent 216 2c3ceb119f0c
child 218 87fd3589b65a
queries optimisation first step
src/egonomy/utils/queries.py
src/egonomy/views.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
--- 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},