diff options
-rw-r--r-- | models.py | 23 | ||||
-rw-r--r-- | views.py | 14 |
2 files changed, 34 insertions, 3 deletions
@@ -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): @@ -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: |