]> git.parisson.com Git - teleforma.git/commitdiff
improve appointments performance
authorYoan Le Clanche <yoan@ellington.pilotsystems.net>
Tue, 6 Nov 2018 16:27:35 +0000 (17:27 +0100)
committerYoan Le Clanche <yoan@ellington.pilotsystems.net>
Tue, 6 Nov 2018 16:27:35 +0000 (17:27 +0100)
teleforma/models/appointment.py
teleforma/templates/teleforma/appointments.html
teleforma/views/appointment.py

index f9dde8a85fb37013e4eb3da12872f50e8536c714..e7f5d6abf676fcaf350cd57d170a292b57678572 100644 (file)
@@ -8,8 +8,19 @@ from django.contrib.auth.models import User
 from django.utils.translation import ugettext_lazy as _
 from django.core import urlresolvers
 from django.utils.functional import cached_property
+from django.core.cache import cache
+CACHE_KEY = 'appointment'
 
 
+def timing(f):
+    def wrap(*args):
+        time1 = time.time()
+        ret = f(*args)
+        time2 = time.time()
+        print '%s function took %0.3f ms' % (f.func_name, (time2-time1)*1000.0)
+        return ret
+    return wrap
+
 class AppointmentPeriod(Model):
     periods = models.ManyToManyField(Period, related_name='appointment_periods',
                                      verbose_name=u"Période")
@@ -47,23 +58,42 @@ class AppointmentPeriod(Model):
         return self.start <= datetime.date.today() <= self.end and self.enable_appointment
 
     @cached_property
+    @timing
     def days(self):
         days = {}
         delay = self.book_delay
         today = datetime.date.today()
 
-        for slot in AppointmentSlot.objects.filter(appointment_period=self):
-            if slot.date not in days:
-                days[slot.date] = {}
-                days[slot.date]['date'] = slot.date
-                days[slot.date]['slots'] = [slot, ]
-                days[slot.date]['available'] = False
+        for slot in AppointmentSlot.objects.filter(appointment_period=self).order_by('start'):
+            cache_key = '%s_%s_%s' % (CACHE_KEY, self.id, slot.date)
+            dayData = cache.get(cache_key)
+            if not dayData:
+                slotData = {'instance':slot,
+                            'slots':slot.slots,
+                            'get_visible_jurys':slot.get_visible_jurys,
+                            'get_nb_of_visible_jurys':slot.get_nb_of_visible_jurys,
+                            'has_available_slot':slot.has_available_slot}
+                if slot.date not in days:
+                    days[slot.date] = {}
+                    days[slot.date]['date'] = slot.date
+                    days[slot.date]['slots'] = [slotData, ]
+                    days[slot.date]['available'] = False
+                else:
+                    days[slot.date]['slots'].append(slotData)
+
+                # days are available if they are within the good period and if there are remaining slots
+                if slotData['has_available_slot'] and self.work_day_between(today, slot.date) >= delay:
+                    days[slot.date]['available'] = True
+                days[slot.date]['from_cache'] = False
             else:
-                days[slot.date]['slots'].append(slot)
+                days[slot.date] = dayData
+                days[slot.date]['from_cache'] = True
+
+        for day in days:
+            if not days[day]['from_cache']:
+                cache_key = '%s_%s_%s' % (CACHE_KEY, self.id, day)
+                cache.set(cache_key, days[day], 1800)
 
-            # days are available if they are within the good period and if there are remaining slots
-            if slot.has_available_slot and self.work_day_between(today, slot.date) >= delay:
-                days[slot.date]['available'] = True
 
         # print days
         return sorted(days.values(), key=lambda d:d['date'])
index f1c7528d37ccbac18216edf55a12789afa6653ff..1231ad44d49a0fc8e83287fd752e9b6843dbe7c7 100644 (file)
                     <section data-day="{{ day.date|date:'Y_m_d' }}" class="booking_day">
                         <h2 class="day">{{ day.date }}</h2>
                         <table border="1">
-{#                            <thead>#}
-{#                            <tr>#}
-{#                                <th>#}
-{#                                    Heure d'arrivé#}
-{#                                </th>#}
-{#                                <th style="display:none">#}
-{#                                    Heure de début#}
-{#                                </th>#}
-{#                                <th style="display:none">#}
-{#                                    Heure de fin#}
-{#                                </th>#}
-{#                                {% for jury in day.available_jurys %}#}
-{#                                    <th>#}
-{#                                        Jury {{ forloop.counter }}#}
-{#                                        <div data-jury="{{ jury.id }}">#}
-{#                                            <input type="hidden" name="jury_name" value="{{ jury.name }}"/>#}
-{#                                            <input type="hidden" name="jury_address" value="{{ jury.address }}"/>#}
-{#                                        </div>#}
-{#                                    </th>#}
-{#                                {% endfor %}#}
-{#                            </tr>#}
-{#                            </thead>#}
                             <tbody>
                             {% for groupslot in day.slots %}
 
                                                             <input type="hidden" name="slot_nb"
                                                                    value="{{ slot.slot_nb }}"/>
                                                             <input type="hidden" name="slot"
-                                                                   value="{{ groupslot.id }}"/>
-                                                            <input type="hidden" name="day" value="{{ day.id }}"/>
+                                                                   value="{{ groupslot.instance.id }}"/>
                                                             <input type="hidden" name="jury" value="{{ jury.id }}"/>
                                                             <button type="submit">Réserver</button>
                                                         </form>
index fc1715732eeeb544dfdc40610e36f535a1e036c0..3f09edfe66ee311fb1f8a4d8b2bb3c59ea8728d8 100644 (file)
@@ -10,8 +10,9 @@ from django.core.urlresolvers import reverse, reverse_lazy
 from django.db import IntegrityError
 from django.core.mail import send_mail
 from django.conf import settings
+from django.core.cache import cache
 
-from teleforma.models.appointment import AppointmentPeriod, Appointment, AppointmentSlot
+from teleforma.models.appointment import AppointmentPeriod, Appointment, AppointmentSlot, CACHE_KEY
 
 from teleforma.views.core import get_periods
 
@@ -98,6 +99,7 @@ class Appointments(View):
             ap.student = user
             try:
                 ap.save()
+                cache.delete('%s_%s_%s' % (CACHE_KEY, ap.slot.appointment_period.id, ap.slot.date))
                 self.send_ap_mail(ap)
             except IntegrityError:
                 # Duplicate appointment caught by the db
@@ -126,6 +128,7 @@ class Appointments(View):
         # DEBUG
         # data['mto'] = "yoanl@pilotsystems.net"
         # data['mto'] = "dorothee.lavalle@pre-barreau.com"
+        # data['mto'] = "gael@pilotsystems.net"
 
         subject_template = 'teleforma/messages/email_appointment_sujet.txt'
         message_template = 'teleforma/messages/email_appointment.txt'
@@ -150,6 +153,7 @@ def cancel_appointment(request):
         messages.add_message(request, messages.ERROR, 'Il est trop tard pour annuler ce rendez-vous.')
         return redirect('teleforma-appointments', period_id=period_id)
 
+    cache.delete('%s_%s_%s' % (CACHE_KEY, app.slot.appointment_period.id, app.slot.date))
     app.delete()
     messages.add_message(request, messages.INFO, 'Votre réservation a été annulé.')
     return redirect('teleforma-appointments', period_id=period_id)