Просмотр исходного кода

Optimise SQL requests in counter.get view

Camille Masset лет назад: 9
Родитель
Сommit
8ba9e9f109
2 измененных файлов с 19 добавлено и 16 удалено
  1. 6 6
      counter/templates/counterTemplate.html
  2. 13 10
      counter/views/counter.py

+ 6 - 6
counter/templates/counterTemplate.html

26
                 </a>
26
                 </a>
27
                 {% if not counter.lastReset.noSeum %}
27
                 {% if not counter.lastReset.noSeum %}
28
                 {% if counter.alreadyLiked %}
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
                 </span>
31
                 </span>
32
                 {% elif counter.id == myCounter.id or counter.lastReset.who.id == myCounter.id %}
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
                 </span>
35
                 </span>
36
                 {% else %}
36
                 {% else %}
37
                 <a class="pull-right badge" onclick="document.forms['like{{counter.id}}'].submit();">
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
                 </a>
39
                 </a>
40
                 {% endif %}
40
                 {% endif %}
41
                 {% endif %}
41
                 {% endif %}
123
                       {{ reset.who.trigramme }}
123
                       {{ reset.who.trigramme }}
124
                     {% endif %}
124
                     {% endif %}
125
                   </td>
125
                   </td>
126
-                  <td>{{ reset.likeCount }}</td>
126
+                  <td>{{ reset.likes_count }}</td>
127
                 </tr>
127
                 </tr>
128
               {% endfor %}
128
               {% endfor %}
129
             </tbody>
129
             </tbody>

+ 13 - 10
counter/views/counter.py

1
 from datetime import datetime, timedelta
1
 from datetime import datetime, timedelta
2
-import copy
2
+from copy import copy
3
 
3
 
4
 from django.contrib.auth.decorators import login_required
4
 from django.contrib.auth.decorators import login_required
5
 from django.core.mail import EmailMessage
5
 from django.core.mail import EmailMessage
6
 from django.core.urlresolvers import reverse
6
 from django.core.urlresolvers import reverse
7
+from django.db.models import Count, Prefetch
7
 from django.http import HttpResponseRedirect
8
 from django.http import HttpResponseRedirect
8
 from django.shortcuts import render
9
 from django.shortcuts import render
9
 from django.template.loader import render_to_string
10
 from django.template.loader import render_to_string
25
     except Counter.DoesNotExist:
26
     except Counter.DoesNotExist:
26
         return HttpResponseRedirect(reverse('login'))
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
     # Display
36
     # Display
33
-    if resets.count() == 0:
37
+    if len(resets) == 0:
34
         counter.lastReset = Reset()
38
         counter.lastReset = Reset()
35
-        counter.lastReset.delta = timezero
39
+        counter.lastReset.delta = timedelta(0)
36
         counter.lastReset.noSeum = True
40
         counter.lastReset.noSeum = True
37
         seumFrequency = _('unknown')
41
         seumFrequency = _('unknown')
38
     else:
42
     else:
39
-        firstReset = resets.reverse()[0]
43
+        firstReset = copy(resets[-1])
40
         counter.lastReset = resets[0]
44
         counter.lastReset = resets[0]
41
         counter.lastReset.noSeum = False
45
         counter.lastReset.noSeum = False
42
         if counter.lastReset.who is None or counter.lastReset.who == counter:
46
         if counter.lastReset.who is None or counter.lastReset.who == counter:
45
             counter.lastReset.selfSeum = False
49
             counter.lastReset.selfSeum = False
46
 
50
 
47
         counter.lastReset.formatted_delta = arrow.Arrow.fromdatetime(counter.lastReset.timestamp).humanize(locale=get_language())
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
         seumFrequency = format_timedelta((datetime.now() - firstReset.timestamp.replace(tzinfo=None)) / counter.seumCount,
53
         seumFrequency = format_timedelta((datetime.now() - firstReset.timestamp.replace(tzinfo=None)) / counter.seumCount,
50
             locale=get_language(), threshold=1)
54
             locale=get_language(), threshold=1)
51
 
55
 
56
             counter.likersString = ", ".join(like.liker.trigramme for like in counter.lastLikes)
60
             counter.likersString = ", ".join(like.liker.trigramme for like in counter.lastLikes)
57
 
61
 
58
     for reset in resets:
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
             reset.selfSeum = True
64
             reset.selfSeum = True
61
         else:
65
         else:
62
             reset.selfSeum = False
66
             reset.selfSeum = False
63
         reset.date = reset.timestamp
67
         reset.date = reset.timestamp
64
-        reset.likeCount = reset.likes.count()
65
 
68
 
66
     # Timeline graph
69
     # Timeline graph
67
     # Data pre-processing
70
     # Data pre-processing