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: | 
