simplify query for collection avancement
authorymh <ymh.work@gmail.com>
Tue, 23 May 2017 18:44:00 +0200
changeset 523 74bed3682231
parent 522 2d9660ad4a94
child 524 a051b60f4b26
simplify query for collection avancement
src/iconolab/models.py
src/iconolab/views/objects.py
--- a/src/iconolab/models.py	Tue May 23 16:35:17 2017 +0200
+++ b/src/iconolab/models.py	Tue May 23 18:44:00 2017 +0200
@@ -9,7 +9,9 @@
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.fields import GenericRelation
 from django.contrib.contenttypes.models import ContentType
-from django.db import models, transaction, connection
+from django.db import connection, models, transaction
+from django.db.models import Count
+from django.utils.functional import cached_property
 from django.utils.text import slugify
 from django_comments_xtd.models import XtdComment
 
@@ -50,33 +52,16 @@
     height = models.IntegerField(null=True, blank=True)
     width = models.IntegerField(null=True, blank=True)
     show_image_on_home = models.BooleanField(default=False)
-    completed_percent_calculated = None
 
+    @cached_property
     def completed_percent(self):
 
-        if self.completed_percent_calculated is None:
-
-            sql = '''SELECT i.id AS item, COUNT(a.id) AS annotations
-    FROM iconolab_collection c
-    JOIN iconolab_item i ON i.collection_id = c.id
-    JOIN iconolab_image img ON img.item_id = i.id
-    LEFT JOIN iconolab_annotation a ON a.image_id = img.id
-    WHERE c.id = %s
-    GROUP BY c.name, i.id'''
+        items_with_annotation = \
+            ImageStats.objects.filter(image__item__collection = self, annotations_count__gt=0)\
+                .values('image__item').distinct().count()
+        total_items = Item.objects.filter(collection=self).count()
 
-            with connection.cursor() as cursor:
-                cursor.execute(sql, [self.id])
-                results = dictfetchall(cursor)
-                total_items = len(results)
-                items_with_annotation = 0
-
-                for result in results:
-                    if result['annotations'] > 0:
-                        items_with_annotation += 1
-
-                self.completed_percent_calculated = int(round((items_with_annotation * 100) / total_items))
-
-        return self.completed_percent_calculated
+        return int(round((items_with_annotation * 100) / total_items))
 
     def __str__(self):
         return self.name
--- a/src/iconolab/views/objects.py	Tue May 23 16:35:17 2017 +0200
+++ b/src/iconolab/views/objects.py	Tue May 23 18:44:00 2017 +0200
@@ -68,9 +68,6 @@
             .order_by('-annotation_count')\
             .all()[:10]
 
-        for collection in context['collections_primary']:
-            collection.completed_percent()
-
         most_accurate_tags = []
         for row in rows:
             tag = Tag.objects.get(id=row['tag'])
@@ -215,7 +212,6 @@
             return result(request)
         context = super(CollectionHomepageView, self).get_context_data(**kwargs)
         context['collection_name'] = self.kwargs.get('collection_name', '')
-        collection.completed_percent()
         context['collection'] = collection
 
         # get Pagination and navigation query args