From 3148aaf7c43866bd672d54ac54a0e70bc71f1020 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 18 Nov 2017 17:14:26 +0100 Subject: Mise en commun du traitement des données avant rendu de l’emploi du temps --- models.py | 13 +++++++++---- views.py | 43 ++++++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/models.py b/models.py index 547c0e1..369a4a6 100644 --- a/models.py +++ b/models.py @@ -157,10 +157,15 @@ class Room(models.Model): class CourseManager(Manager): - def get_courses_for_group(self, group, **criteria): - return self.get_queryset() \ - .filter(groups__in=Group.objects.get_parents(group), **criteria) \ - .order_by("begin").prefetch_related("rooms") + def get_courses(self, obj, **criteria): + qs = self.get_queryset() + if isinstance(obj, Group): + qs = qs.filter(groups__in=Group.objects.get_parents(obj), **criteria) \ + .prefetch_related("rooms") + elif isinstance(obj, Room): + qs = qs.filter(rooms__in=(obj,), **criteria) + + return qs.order_by("begin") def get_weeks(self, **criteria): return self.get_queryset() \ diff --git a/views.py b/views.py index 3916fac..428711f 100644 --- a/views.py +++ b/views.py @@ -61,7 +61,7 @@ def group_list(request, year_slug, timetable_slug): return render(request, "group_list.html", {"timetable": timetable, "groups": groups}) -def timetable(request, year_slug, timetable_slug, group_slug, year=None, week=None): +def timetable_common(request, obj, year=None, week=None): current_year, current_week = get_current_or_next_week() is_old_timetable, provided_week = False, True @@ -73,21 +73,30 @@ def timetable(request, year_slug, timetable_slug, group_slug, year=None, week=No start, end = get_week(year, week) - timetable = get_object_or_404(Timetable, year__slug=year_slug, slug=timetable_slug) - group = get_object_or_404(Group, slug=group_slug, timetable=timetable) - - courses = Course.objects.get_courses_for_group(group, begin__gte=start, begin__lt=end) + courses = Course.objects.get_courses(obj, begin__gte=start, begin__lt=end) if not courses.exists() and provided_week: raise Http404 last_update = courses.aggregate(Max("last_update"))["last_update__max"] grouped_courses = group_courses(courses) - return render(request, "timetable.html", {"group": group, "courses": grouped_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}) +def timetable(request, year_slug, timetable_slug, group_slug, year=None, week=None): + timetable = get_object_or_404(Timetable, year__slug=year_slug, slug=timetable_slug) + group = get_object_or_404(Group, slug=group_slug, timetable=timetable) + + if Group.objects.filter(timetable=timetable, mention=group.mention, + subgroup__startswith=group.subgroup).count() > 1: + subgroups = Group.objects.get_relevant_groups(timetable, mention=group.mention, + subgroup__startswith=group.subgroup) + return group_list_common(request, timetable, subgroups) + + return timetable_common(request, group, year, week) + def calendars(request, year_slug, timetable_slug, group_slug): group = get_object_or_404(Group, timetable__year__slug=year_slug, timetable__slug=timetable_slug, slug=group_slug) @@ -102,32 +111,40 @@ def rooms(request): end = start + datetime.timedelta(weeks=4) # Récupération des salles et de toutes les semaines où elles sont - # concernées - # Cette requête est un peu lente sur sqlite… - # Par contre c’est beaucoup plus rapide sur PostgreSQL + # concernées. + # Cette requête associe chaque salle à toutes les semaines où un + # cours s’y déroule. Le résultat est trié par le nom de la salle + # et par semaine. + # TODO optimiser cette requête, elle me semble un peu lente rooms = Room.objects.filter(course__begin__gte=start, course__begin__lt=end) \ .order_by("name") \ .annotate(year=ExtractYear("course__begin"), week=ExtractWeek("course__begin"), c=Count("*")) + # Regroupement des semaines dans une liste de chaque objet salle rooms_weeks = [] for room in rooms: + # Si on a pas traité de salle ou que la salle courante + # dans le résultat de la requête est différente de la dernière + # dans la liste des salles traitées if len(rooms_weeks) == 0 or rooms_weeks[-1].id != room.id: + # On lui affecte un tableau et on l’ajoute dans + # la liste des salles à traiter room.weeks = [] rooms_weeks.append(room) + # On récupère le premier jour de la semaine date, _ = get_week(room.year, room.week) + # Et on le rajoute dans la liste des semaines de la salle. rooms_weeks[-1].weeks.append(date) + # Rendu de la page. return render(request, "group_list.html", {"groups": rooms_weeks}) def room_timetable(request, room_slug, year=None, week=None): room = get_object_or_404(Room, slug=room_slug) - courses = Course.objects.filter(rooms__in=(room,)).order_by("begin") - - return render(request, "timetable.html", {"group": room, "courser": courses, - }) + return timetable_common(request, room, year, week) def ctx_processor(request): return {"celcatsanitizer_version": edt.VERSION} -- cgit v1.2.1