From: Yoan Le Clanche Date: Tue, 6 Nov 2018 16:27:35 +0000 (+0100) Subject: improve appointments performance X-Git-Tag: 1.4.0~29 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=5941d75737e78377c5744020632f5a00c292e90b;p=teleforma.git improve appointments performance --- diff --git a/teleforma/models/appointment.py b/teleforma/models/appointment.py index f9dde8a8..e7f5d6ab 100644 --- a/teleforma/models/appointment.py +++ b/teleforma/models/appointment.py @@ -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']) diff --git a/teleforma/templates/teleforma/appointments.html b/teleforma/templates/teleforma/appointments.html index f1c7528d..1231ad44 100644 --- a/teleforma/templates/teleforma/appointments.html +++ b/teleforma/templates/teleforma/appointments.html @@ -211,28 +211,6 @@

{{ day.date }}

-{# #} -{# #} -{# #} -{# #} -{# #} -{# {% for jury in day.available_jurys %}#} -{# #} -{# {% endfor %}#} -{# #} -{# #} {% for groupslot in day.slots %} @@ -270,8 +248,7 @@ - + value="{{ groupslot.instance.id }}"/> diff --git a/teleforma/views/appointment.py b/teleforma/views/appointment.py index fc171573..3f09edfe 100644 --- a/teleforma/views/appointment.py +++ b/teleforma/views/appointment.py @@ -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)
#} -{# Heure d'arrivé#} -{# #} -{# Heure de début#} -{# #} -{# Heure de fin#} -{# #} -{# Jury {{ forloop.counter }}#} -{#
#} -{# #} -{# #} -{#
#} -{#