Pārlūkot izejas kodu

Optimise SQL requests in counter.get view

Camille Masset 9 gadi atpakaļ
vecāks
revīzija
8ba9e9f109
2 mainītis faili ar 19 papildinājumiem un 16 dzēšanām
  1. 6 6
      counter/templates/counterTemplate.html
  2. 13 10
      counter/views/counter.py

+ 6 - 6
counter/templates/counterTemplate.html

@@ -26,16 +26,16 @@
26 26
                 </a>
27 27
                 {% if not counter.lastReset.noSeum %}
28 28
                 {% if counter.alreadyLiked %}
29
-                <span class="pull-right badge" {% if counter.likeCount > 0 %} data-toggle="tooltip" data-placement="top" title="{{ counter.likersString }}" {% endif %}>
30
-                    <span class="glyphicon glyphicon-ok"></span>&emsp;{{ counter.likeCount }}
29
+                <span class="pull-right badge" {% if counter.likes_count > 0 %} data-toggle="tooltip" data-placement="top" title="{{ counter.likersString }}" {% endif %}>
30
+                    <span class="glyphicon glyphicon-ok"></span>&emsp;{{ counter.likes_count }}
31 31
                 </span>
32 32
                 {% elif counter.id == myCounter.id or counter.lastReset.who.id == myCounter.id %}
33
-                <span class="pull-right badge" {% if counter.likeCount > 0 %} data-toggle="tooltip" data-placement="top" title="{{ counter.likersString }}" {% endif %}>
34
-                    <span class="glyphicon glyphicon-heart"></span>&emsp;{{ counter.likeCount }}
33
+                <span class="pull-right badge" {% if counter.likes_count > 0 %} data-toggle="tooltip" data-placement="top" title="{{ counter.likersString }}" {% endif %}>
34
+                    <span class="glyphicon glyphicon-heart"></span>&emsp;{{ counter.likes_count }}
35 35
                 </span>
36 36
                 {% else %}
37 37
                 <a class="pull-right badge" onclick="document.forms['like{{counter.id}}'].submit();">
38
-                    <span class="glyphicon glyphicon-heart"></span>&emsp;{{ counter.likeCount }}
38
+                    <span class="glyphicon glyphicon-heart"></span>&emsp;{{ counter.likes_count }}
39 39
                 </a>
40 40
                 {% endif %}
41 41
                 {% endif %}
@@ -123,7 +123,7 @@
123 123
                       {{ reset.who.trigramme }}
124 124
                     {% endif %}
125 125
                   </td>
126
-                  <td>{{ reset.likeCount }}</td>
126
+                  <td>{{ reset.likes_count }}</td>
127 127
                 </tr>
128 128
               {% endfor %}
129 129
             </tbody>

+ 13 - 10
counter/views/counter.py

@@ -1,9 +1,10 @@
1 1
 from datetime import datetime, timedelta
2
-import copy
2
+from copy import copy
3 3
 
4 4
 from django.contrib.auth.decorators import login_required
5 5
 from django.core.mail import EmailMessage
6 6
 from django.core.urlresolvers import reverse
7
+from django.db.models import Count, Prefetch
7 8
 from django.http import HttpResponseRedirect
8 9
 from django.shortcuts import render
9 10
 from django.template.loader import render_to_string
@@ -25,18 +26,21 @@ def get(request, id_counter):
25 26
     except Counter.DoesNotExist:
26 27
         return HttpResponseRedirect(reverse('login'))
27 28
 
28
-    counter = Counter.objects.prefetch_related('resets', 'resets__likes').get(pk=id_counter)
29
-    resets = counter.resets.order_by('-timestamp')
30
-    timezero = timedelta(0)
29
+    counter = Counter.objects.prefetch_related(
30
+        # we get the related resets annotated with their number of likes
31
+        Prefetch('resets', queryset=Reset.objects.annotate(likes_count=Count('likes'))),
32
+        'resets__likes'
33
+    ).get(pk=id_counter)
34
+    resets = list(counter.resets.order_by('-timestamp'))
31 35
 
32 36
     # Display
33
-    if resets.count() == 0:
37
+    if len(resets) == 0:
34 38
         counter.lastReset = Reset()
35
-        counter.lastReset.delta = timezero
39
+        counter.lastReset.delta = timedelta(0)
36 40
         counter.lastReset.noSeum = True
37 41
         seumFrequency = _('unknown')
38 42
     else:
39
-        firstReset = resets.reverse()[0]
43
+        firstReset = copy(resets[-1])
40 44
         counter.lastReset = resets[0]
41 45
         counter.lastReset.noSeum = False
42 46
         if counter.lastReset.who is None or counter.lastReset.who == counter:
@@ -45,7 +49,7 @@ def get(request, id_counter):
45 49
             counter.lastReset.selfSeum = False
46 50
 
47 51
         counter.lastReset.formatted_delta = arrow.Arrow.fromdatetime(counter.lastReset.timestamp).humanize(locale=get_language())
48
-        counter.seumCount = counter.resets.count()
52
+        counter.seumCount = len(resets)
49 53
         seumFrequency = format_timedelta((datetime.now() - firstReset.timestamp.replace(tzinfo=None)) / counter.seumCount,
50 54
             locale=get_language(), threshold=1)
51 55
 
@@ -56,12 +60,11 @@ def get(request, id_counter):
56 60
             counter.likersString = ", ".join(like.liker.trigramme for like in counter.lastLikes)
57 61
 
58 62
     for reset in resets:
59
-        if reset.who is None or reset.who == reset.counter:
63
+        if reset.who is None or reset.who.id == reset.counter.id:
60 64
             reset.selfSeum = True
61 65
         else:
62 66
             reset.selfSeum = False
63 67
         reset.date = reset.timestamp
64
-        reset.likeCount = reset.likes.count()
65 68
 
66 69
     # Timeline graph
67 70
     # Data pre-processing