diff options
Diffstat (limited to 'views.py')
-rw-r--r-- | views.py | 51 |
1 files changed, 38 insertions, 13 deletions
@@ -15,6 +15,7 @@ import datetime +from django.db import connection from django.db.models import Count, Max from django.db.models.functions import ExtractWeek, ExtractYear, Length from django.http import Http404 @@ -29,6 +30,9 @@ from .utils import get_current_week, get_current_or_next_week, get_week, \ import edt +if connection.vendor == "postgresql": + from django.contrib.postgres.aggregates import ArrayAgg + from django.db.models.expressions import RawSQL def index(request): years = Year.objects.order_by("name") @@ -44,16 +48,13 @@ def mention_list(request, year_slug): def group_list(request, year_slug, timetable_slug): - timetable = get_object_or_404(Timetable, year__slug=year_slug, - slug=timetable_slug) - groups = Group.objects.filter(source=timetable.source, hidden=False) \ - .order_by("name") + timetable = get_object_or_404(Timetable, year__slug=year_slug, slug=timetable_slug) start, _ = get_week(*get_current_week()) end = start + datetime.timedelta(weeks=4) - groups_weeks = Course.objects.get_weeks(begin__gte=start, begin__lt=end, - groups__in=groups) + groups = Group.objects.get_relevant_groups(start, source=timetable.source, hidden=False) + groups_weeks = Course.objects.get_weeks(begin__gte=start, begin__lt=end, groups__in=groups) for group in groups: for group_week in groups_weeks: @@ -90,16 +91,22 @@ def timetable_common(request, obj, year=None, week=None, timetable=None): if not courses.exists() and provided_week: raise Http404 + # Récupération des semaines suivantes et précédentes pour les + # afficher proprement dans l’emploi du temps + last_week = getattr(Course.objects.get_courses(obj, begin__lt=start).last(), "begin", None) + next_week = getattr(Course.objects.get_courses(obj, begin__gte=end).first(), "begin", None) + last_update = courses.aggregate(Max("last_update"))["last_update__max"] grouped_courses = group_courses(courses) - return render(request, "timetable.html", - {"group": obj, "courses": grouped_courses, - "last_update": last_update, "year": year, "week": int(week), - "is_old_timetable": is_old_timetable, - "group_mode": isinstance(obj, Group), - "timetable": timetable}) - + return render(request, "timetable.html", {"group": obj, "courses": grouped_courses, + "last_update": last_update, + "year": year, "week": int(week), + "last_week": last_week, + "next_week": next_week, + "is_old_timetable": is_old_timetable, + "group_mode": isinstance(obj, Group), + "timetable": timetable}) def timetable(request, year_slug, timetable_slug, group_slug, year=None, week=None): @@ -127,6 +134,24 @@ def rooms(request): start, _ = get_week(*get_current_week()) end = start + datetime.timedelta(weeks=4) + if connection.vendor == "postgresql": + # Si le SGBD est PostgreSQL, on utilise une requête à base de + # ArrayAgg. Elle présente l’avantage d’être plus rapide que la + # requête « généraliste » et de ne pas nécessiter de + # traitement après. On récupère chaque salle ayant un cours + # dans le mois à venir. Pour chacun de ses cours, on ne + # récupère que le premier jour de la semaine, et si jamais ce + # jour n’est pas déjà dans la liste des semaines de cours + # (« weeks »), on l’y rajoute. + rooms = Room.objects.filter(course__begin__gte=start, + course__begin__lt=end) \ + .order_by("name") \ + .annotate(weeks=ArrayAgg( + RawSQL("date_trunc('week', edt_course.begin)", + []), distinct=True)) + + return render(request, "group_list.html", {"groups": rooms}) + # Récupération des salles et de toutes les semaines où elles sont # concernées. # Cette requête associe chaque salle à toutes les semaines où un |