Development #43306
Réduire le nombre de queryset sur les pages day/month d'un calendrier
0%
Description
Ajouter quelques prefetch bien placés
Fichiers
Révisions associées
agendas: reduce querysets on day/month views (#43306)
Historique
Mis à jour par Lauréline Guérin il y a presque 4 ans
- Fichier 0002-agendas-reduce-querysets-on-day-month-views-43306.patch 0002-agendas-reduce-querysets-on-day-month-views-43306.patch ajouté
- Fichier 0001-agendas-add-tests-on-queryset-for-day-month-views-43.patch 0001-agendas-add-tests-on-queryset-for-day-month-views-43.patch ajouté
- Statut changé de Nouveau à Solution proposée
- Patch proposed changé de Non à Oui
def get_opening_hours(self, date):
if hasattr(self, 'prefetched_timeperiods'):
timeperiods = self.prefetched_timeperiods
else:
timeperiods = self.timeperiod_set.all()
openslots = IntervalSet()
for timeperiod in timeperiods:
if timeperiod.weekday != date.weekday():
continue
start_datetime = make_aware(datetime.datetime.combine(date, timeperiod.start_time))
end_datetime = make_aware(datetime.datetime.combine(date, timeperiod.end_time))
openslots.add(start_datetime, end_datetime)
if hasattr(self, 'prefetched_exceptions'):
timeexceptions = self.prefetched_exceptions
else:
timeexceptions = self.timeperiodexception_set.all()
aware_date = make_aware(datetime.datetime(date.year, date.month, date.day))
exceptions = IntervalSet()
aware_next_date = aware_date + datetime.timedelta(days=1)
for exception in timeexceptions:
if exception.end_datetime < aware_date:
continue
if exception.start_datetime > aware_next_date:
continue
exceptions.add(exception.start_datetime, exception.end_datetime)
return [OpeningHour(*time_range) for time_range in (openslots - exceptions)]
J'ai utilisé des prefetch pour les time periods et les exceptions, quitte à devoir filtrer à la main plutôt que passer par un queryset filtrant:
sur la vue month, on appelle cette méthode pour chaque jour affiché, ce qui fait autant de querysets.
(les exceptions étaient déjà prefetch dans la vue, autant les réutiliser dans la méthode get_opening_hours
)
Mis à jour par Benjamin Dauvergne il y a presque 4 ans
Il me semble1 que passer par self.prefetched_truc
est inutile, si tu prefetch une propriété truc_set
alors instance.truc_set.all()
utilise la valeur préfetchée (et uniquement via .all()
si tu filtres par n'importe quoi d'autre ça n'utilise plus la valeur préfetchée, ça refait une requête).
Donc tu dois pouvoir simplifier les choses ainsi
- .prefetch_related(Prefetch('timeperiod_set', to_attr='prefetched_timeperiods')) + .prefetch_related('timeperiod_set') .... - if hasattr(self, 'prefetched_timeperiods'): - timeperiods = self.prefetched_timeperiods - else: - timeperiods = self.timeperiod_set.all() + timeperiods = self.timeperiod_set.all()
Mis à jour par Benjamin Dauvergne il y a presque 4 ans
- Statut changé de Solution proposée à En cours
Mis à jour par Lauréline Guérin il y a presque 4 ans
- Fichier 0002-toulouse-axel-fix-handicap-fields-when-not-to-update.patch 0002-toulouse-axel-fix-handicap-fields-when-not-to-update.patch ajouté
- Fichier 0001-toulouse_axel-fix-allergie-fields-when-block-is-not-.patch 0001-toulouse_axel-fix-allergie-fields-when-block-is-not-.patch ajouté
- Statut changé de En cours à Solution proposée
Je sais bien, mais j'aime bien en général poser mes prefetch dans un to_attr: c'est plus explicite, à la lecture du code on sait de suite d'où ça vient.
Je voulais éviter qu'on soit dans le futur tentés de remettre un queryset filtré dans la méthode get_opening_hours
: si on voit que c'est prefetché alors on sait qu'on ne doit pas y toucher sans y avoir mûrement réfléchi.
Mais, ça se tient, sans to_attr on peut reduire un peu le code :) Du coup j'ai posé des commentaires.
Mis à jour par Lauréline Guérin il y a presque 4 ans
- Fichier 0002-agendas-reduce-querysets-on-day-month-views-43306.patch 0002-agendas-reduce-querysets-on-day-month-views-43306.patch ajouté
- Fichier 0001-agendas-add-tests-on-queryset-for-day-month-views-43.patch 0001-agendas-add-tests-on-queryset-for-day-month-views-43.patch ajouté
mauvaises pièces jointes :/
Mis à jour par Benjamin Dauvergne il y a presque 4 ans
- Statut changé de Solution proposée à Solution validée
Lauréline Guerin a écrit :
Je voulais éviter qu'on soit dans le futur tentés de remettre un queryset filtré dans la méthode
get_opening_hours
: si on voit que c'est prefetché alors on sait qu'on ne doit pas y toucher sans y avoir mûrement réfléchi.
Les tests sur le nombre de query évite facilement ce genre d'accident.
Mis à jour par Lauréline Guérin il y a presque 4 ans
- Statut changé de Solution validée à Résolu (à déployer)
commit 1119909e34a94a1adeb282ad3757f34ba21e16e7 Author: Lauréline Guérin <zebuline@entrouvert.com> Date: Mon May 25 14:52:08 2020 +0200 agendas: reduce querysets on day/month views (#43306) commit 06ee841b111cbc9f5819091f3d518605dd5b0513 Author: Lauréline Guérin <zebuline@entrouvert.com> Date: Mon May 25 14:47:11 2020 +0200 agendas: add tests on queryset for day/month views (#43306)
Mis à jour par Frédéric Péters il y a presque 4 ans
- Statut changé de Résolu (à déployer) à Solution déployée
agendas: add tests on queryset for day/month views (#43306)