aboutsummaryrefslogtreecommitdiff
path: root/models.py
diff options
context:
space:
mode:
authorAlban Gruin2018-01-27 21:59:42 +0100
committerAlban Gruin2018-01-27 21:59:42 +0100
commit0aceecf04cf720525772a9801d7799f19e5a3cd1 (patch)
tree398c26c5a558ae4d52d725a4ea353fd9230cbbc3 /models.py
parentee94b9e48dc2b632f876702df57136f394ee5574 (diff)
Remplacement de la requête de QSJPS par une autre, plus simple et plus
rapide à exécuter sur de gros volumes de données. On aura peut-être besoin d’utiliser un double index pour augmenter encore plus les performances. La requête liste tous les cours commençant avant la fin de l’intervalle et finissant après le début de l’intervalle, en excluant les cours n’ayant pas de salle assignée. On récupère ensuite la liste des salles de ces cours, et on inverse le contenu de la liste. On trie ensuite les cours par leur nom.
Diffstat (limited to 'models.py')
-rw-r--r--models.py33
1 files changed, 13 insertions, 20 deletions
diff --git a/models.py b/models.py
index e907944..8ff9359 100644
--- a/models.py
+++ b/models.py
@@ -16,7 +16,7 @@
from functools import reduce
from django.db import models
-from django.db.models import Manager, OuterRef, Q, Subquery, Value
+from django.db.models import Manager, Q
from django.db.models.functions import ExtractWeek, ExtractYear
from django.utils import timezone
from django.utils.text import slugify
@@ -162,26 +162,19 @@ class Group(SlugModel):
class RoomManager(Manager):
def qsjps(self, begin, end):
- # On compte tous les cours correspondant à chaque salle
- # commençant avant la fin de l’intervalle et finissant après
- # le début de l’intervalle. Ces cours se trouvent à un moment
- # dans l’intervalle, et la salle assignée à ce cours ne peut
- # donc pas être sélectionnée. Pour accélérer la requête, on
- # s’arrête au premier cours trouvé.
+ # On récupère la liste des cours qui commencent avant la fin
+ # de l’intervalle sélectionné et qui terminent après le début
+ # de l’intervalle, c’est-à-dire qu’au moins une partie du
+ # cours se déroule pendant l’intervalle. On récupère ensuite
+ # la liste des salles dans lesquelles se déroulent ces
+ # cours. On exclu les cours n’ayant aucune salle assignée.
courses = Course.objects.filter(begin__lt=end, end__gt=begin,
- rooms=OuterRef("pk")) \
- .annotate(c=Value(1,
- output_field=models.IntegerField())) \
- .values_list("c", flat=True)[:1]
-
- # On sélectionne toutes les salles qui n’ont aucun de cours se
- # trouvant au moins en partie dans l’intervalle entré par
- # l’utilisateur.
- rooms = self.get_queryset().annotate(
- c=Subquery(courses, output_field=models.IntegerField())) \
- .filter(c__isnull=True).order_by("name")
-
- return rooms
+ rooms__isnull=False) \
+ .values_list("rooms", flat=True)
+
+ # On sélectionne ensuite les salles qui ne sont pas dans la
+ # liste récupérée plus haut, et on les trie par leur nom.
+ return self.get_queryset().exclude(pk__in=courses).order_by("name")
class Room(SlugModel):