aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlban Gruin2018-01-27 19:57:02 +0100
committerAlban Gruin2018-01-27 20:04:05 +0100
commitee94b9e48dc2b632f876702df57136f394ee5574 (patch)
treeacf33c2a4f42d6de05d9738a270a544250d530b1
parent661fbb63d8f6e3607e7449b25f45613a08a1c6bb (diff)
Requête de QSJPS
Pour chaque salle, on compte tous les cours commençant avant la fin de l’intervalle entré par l’utilisateur et finissant après le début de cet intervalle. Tous les cours correspondant à cette requête se trouvent au moins en partie sur l’intervalle. On sélectionne ensuite les salles n’ayant pas de cours correspondant à la requête précédente.
-rw-r--r--models.py23
-rw-r--r--views.py14
2 files changed, 34 insertions, 3 deletions
diff --git a/models.py b/models.py
index 1a638ac..e907944 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, Q
+from django.db.models import Manager, OuterRef, Q, Subquery, Value
from django.db.models.functions import ExtractWeek, ExtractYear
from django.utils import timezone
from django.utils.text import slugify
@@ -162,7 +162,26 @@ class Group(SlugModel):
class RoomManager(Manager):
def qsjps(self, begin, end):
- return None
+ # 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é.
+ 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
class Room(SlugModel):
diff --git a/views.py b/views.py
index 0231c9e..e79de47 100644
--- a/views.py
+++ b/views.py
@@ -19,6 +19,7 @@ from django.db.models import Count, Max
from django.db.models.functions import ExtractWeek, ExtractYear, Length
from django.http import Http404
from django.shortcuts import get_object_or_404, render
+from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
from .forms import QSJPSForm
@@ -153,7 +154,18 @@ def qsjps(request):
form = QSJPSForm(request.POST)
if form.is_valid():
# Formulaire validé
- return render(request, "qsjps.html", {"rooms": [], "form": form})
+ day = form.cleaned_data["day"]
+ begin_hour = form.cleaned_data["begin"]
+ end_hour = form.cleaned_data["end"]
+
+ begin = timezone.make_aware(datetime.datetime.combine(day,
+ begin_hour))
+ end = timezone.make_aware(datetime.datetime.combine(day, end_hour))
+
+ rooms = Room.objects.qsjps(begin, end)
+ return render(request, "qsjps.html", {"rooms": rooms,
+ "form": form})
+
# Si le formulaire est invalide, on ré-affiche le formulaire
# avec les erreurs
else: