diff options
| author | Alban Gruin | 2018-01-27 19:57:02 +0100 | 
|---|---|---|
| committer | Alban Gruin | 2018-01-27 20:04:05 +0100 | 
| commit | ee94b9e48dc2b632f876702df57136f394ee5574 (patch) | |
| tree | acf33c2a4f42d6de05d9738a270a544250d530b1 | |
| parent | 661fbb63d8f6e3607e7449b25f45613a08a1c6bb (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.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:  | 
