From 72dcae5c9d58005af71b293d1ec09a4c50335c64 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 9 Oct 2017 23:11:16 +0200 Subject: Lorsque le nom d’un cours et son champ remarque est vide, le nom de l’objet cours final était égal à None et faisait crasher les flux RSS et Atom, ainsi que l’ICS et n’affichait aucun cours à la semaine du cours problématique. C’est maintenant corrigé. --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index ec141a2..e48efa5 100644 --- a/models.py +++ b/models.py @@ -176,7 +176,7 @@ class Course(models.Model): objects = CourseManager() name = models.CharField(max_length=255, verbose_name="nom", default="Sans nom", - null=True) + null=True) # TODO 0.11: null=False type_ = models.CharField(name="type", max_length=255, verbose_name="type de cours", null=True) timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, -- cgit v1.2.1 From e2fb71d3377dee14cf1934ac3d6ad448bb7063bc Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 10 Oct 2017 21:35:55 +0200 Subject: Un cours doit obligatoirement avoir un nom --- models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index e48efa5..fbbf877 100644 --- a/models.py +++ b/models.py @@ -175,8 +175,7 @@ class CourseManager(Manager): class Course(models.Model): objects = CourseManager() - name = models.CharField(max_length=255, verbose_name="nom", default="Sans nom", - null=True) # TODO 0.11: null=False + name = models.CharField(max_length=255, verbose_name="nom", default="Sans nom") type_ = models.CharField(name="type", max_length=255, verbose_name="type de cours", null=True) timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, -- cgit v1.2.1 From 044e7412856aeefa3c82b39130aa8df6582a0826 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 19:04:23 +0200 Subject: Suppressions des champs td, tp et parents --- models.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index fbbf877..bfc026b 100644 --- a/models.py +++ b/models.py @@ -92,11 +92,6 @@ class Group(models.Model): mention = models.CharField(max_length=128) subgroup = models.CharField(max_length=1, verbose_name="sous-groupe", null=True) - td = models.IntegerField(verbose_name="groupe de TD", null=True) - tp = models.IntegerField(verbose_name="groupe de TP", null=True) - parent = models.ForeignKey("self", verbose_name="groupe parent", null=True, - default=None, related_name="children") - slug = models.SlugField(max_length=64, default="") hidden = models.BooleanField(verbose_name="caché", default=False) @@ -110,7 +105,7 @@ class Group(models.Model): @property def group_info(self): - return self.timetable.id, self.mention, self.subgroup, self.td, self.tp + return self.timetable.id, self.mention, self.subgroup def __str__(self): return self.name @@ -120,12 +115,12 @@ class Group(models.Model): self.name = self.celcat_name self.slug = slugify(self.name) - self.mention, self.subgroup, self.td, self.tp = parse_group(self.name) + self.mention, self.subgroup = parse_group(self.name) super(Group, self).save() class Meta: - index_together = ("mention", "subgroup", "td", "tp",) + index_together = ("mention", "subgroup",) unique_together = (("name", "timetable",), ("celcat_name", "timetable",), ("slug", "timetable",),) -- cgit v1.2.1 From 05b8c81e21dbd33680683238ee044d20a9882a04 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 21:38:40 +0200 Subject: Suppression des champs retirés de l’interface d’administration. La longueur du champ sous-groupe est maintenant fixée à 16. --- models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index bfc026b..868cbd1 100644 --- a/models.py +++ b/models.py @@ -90,8 +90,9 @@ class Group(models.Model): verbose_name="emploi du temps") mention = models.CharField(max_length=128) - subgroup = models.CharField(max_length=1, verbose_name="sous-groupe", + subgroup = models.CharField(max_length=16, verbose_name="sous-groupe", null=True) + slug = models.SlugField(max_length=64, default="") hidden = models.BooleanField(verbose_name="caché", default=False) -- cgit v1.2.1 From f033f310ac8331de24a5fc2028ba22978c1d941e Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 21:48:39 +0200 Subject: Adaptation de corresponds_to() et des tests de parsage --- models.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 868cbd1..c69bec3 100644 --- a/models.py +++ b/models.py @@ -97,12 +97,15 @@ class Group(models.Model): hidden = models.BooleanField(verbose_name="caché", default=False) - def corresponds_to(self, timetable_id, mention, subgroup, td, tp): + def corresponds_to(self, timetable_id, mention, subgroup): + subgroup_corresponds = True + if self.subgroup is not None and subgroup is not None: + subgroup_corresponds = subgroup.startswith(self.subgroup) or \ + self.subgroup.startswith(subgroup) + return self.timetable.id == timetable_id and \ self.mention.startswith(mention) and \ - (self.subgroup == subgroup or self.subgroup is None) and \ - (self.td == td or self.td is None or td is None) and \ - (self.tp == tp or self.tp is None or tp is None) + subgroup_corresponds @property def group_info(self): -- cgit v1.2.1 From 5489101669d57c834c65f5a889a6d40ce3bcfb1c Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 22:14:28 +0200 Subject: Changement de la logique de récupération des cours pour un groupe adaptée à la nouvelle structure du modèle Group. --- models.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index c69bec3..fe285ac 100644 --- a/models.py +++ b/models.py @@ -13,6 +13,8 @@ # You should have received a copy of the GNU Affero General Public License # along with celcatsanitizer. If not, see . +from functools import reduce + from django.db import models from django.db.models import Count, Manager, Q from django.db.models.functions import ExtractWeek, ExtractYear @@ -147,17 +149,13 @@ class Room(models.Model): class CourseManager(Manager): def get_courses_for_group(self, group, **criteria): - groups_criteria = [] - if group.subgroup is not None: - groups_criteria.append(Q(groups__subgroup__isnull=True) | \ - Q(groups__subgroup=group.subgroup)) - if group.td is not None: - groups_criteria.append(Q(groups__td__isnull=True) | Q(groups__td=group.td)) - if group.tp is not None: - groups_criteria.append(Q(groups__tp__isnull=True) | Q(groups__tp=group.tp)) + groups_criteria = reduce(lambda x, y: x | y, + [Q(groups__subgroup=group.subgroup[:i]) + for i in range(1, len(group.subgroup))]) | \ + Q(groups__subgroup__isnull=True) return self.get_queryset() \ - .filter(*groups_criteria, + .filter(groups_criteria, groups__mention=group.mention, timetable=group.timetable, **criteria) \ .order_by("begin") -- cgit v1.2.1 From 86efcdcd2df04a59eb5f27212d8d41f60f861f6c Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 22:48:16 +0200 Subject: Adaptation des vues, correction du critère de sélection des groupes --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index fe285ac..db9e262 100644 --- a/models.py +++ b/models.py @@ -151,7 +151,7 @@ class CourseManager(Manager): def get_courses_for_group(self, group, **criteria): groups_criteria = reduce(lambda x, y: x | y, [Q(groups__subgroup=group.subgroup[:i]) - for i in range(1, len(group.subgroup))]) | \ + for i in range(1, len(group.subgroup) + 1)]) | \ Q(groups__subgroup__isnull=True) return self.get_queryset() \ -- cgit v1.2.1 From b7773b892ee68209feb33870496985f78243681a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Fri, 20 Oct 2017 13:29:07 +0200 Subject: Modification de la requête qui sélectionne les groupes pertinents. --- models.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index db9e262..74fab9e 100644 --- a/models.py +++ b/models.py @@ -16,7 +16,8 @@ from functools import reduce from django.db import models -from django.db.models import Count, Manager, Q +from django.db.models import Count, Manager, Q, Subquery +from django.db.models.expressions import OuterRef from django.db.models.functions import ExtractWeek, ExtractYear from django.utils import timezone from django.utils.text import slugify @@ -69,17 +70,13 @@ class Timetable(SlugModel): class GroupManager(Manager): - def get_relevant_children(self, group): - parent_in = self.get_queryset().filter(parent=group) - return self.get_queryset().filter(Q(parent=group) | Q(parent__in=parent_in)) \ - .annotate(children_count=Count("children")) \ - .filter(children_count=0, hidden=False) \ - .order_by("name") - - def get_relevant_groups(self, *args, **criteria): - return self.get_queryset().filter(*args, **criteria) \ - .annotate(children_count=Count("children")) \ - .filter(children_count=0, hidden=False) + def get_relevant_groups(self, timetable, *args, **criteria): + sub = Group.objects.filter(timetable=timetable,mention=OuterRef("mention"), + subgroup__startswith=OuterRef("subgroup")) \ + .order_by().values("mention").annotate(c=Count("*")).values("c") + return Group.objects.filter(*args, timetable=timetable, hidden=False, **criteria) \ + .annotate(nbsub=Subquery(sub, output_field=models.IntegerField())) \ + .filter(nbsub=1).order_by("name") class Group(models.Model): -- cgit v1.2.1 From 827641acd0b2c64feb704bae989b139458a3d0ca Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Fri, 27 Oct 2017 09:37:25 +0200 Subject: Fonction pour récupérer les parents d’un groupe --- models.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 74fab9e..c546737 100644 --- a/models.py +++ b/models.py @@ -70,11 +70,21 @@ class Timetable(SlugModel): class GroupManager(Manager): + def get_parents(self, group): + groups_criteria = Q(subgroup__isnull=True) | \ + reduce(lambda x, y: x | y, + [Q(subgroup=group.subgroup[:i]) + for i in range(1, len(group.subgroup) + 1)]) + + return self.get_queryset().filter(groups_criteria, mention=group.mention, + timetable=group.timetable) + def get_relevant_groups(self, timetable, *args, **criteria): sub = Group.objects.filter(timetable=timetable,mention=OuterRef("mention"), subgroup__startswith=OuterRef("subgroup")) \ .order_by().values("mention").annotate(c=Count("*")).values("c") - return Group.objects.filter(*args, timetable=timetable, hidden=False, **criteria) \ + + return self.get_queryset().filter(*args, timetable=timetable, hidden=False, **criteria) \ .annotate(nbsub=Subquery(sub, output_field=models.IntegerField())) \ .filter(nbsub=1).order_by("name") @@ -146,15 +156,8 @@ class Room(models.Model): class CourseManager(Manager): def get_courses_for_group(self, group, **criteria): - groups_criteria = reduce(lambda x, y: x | y, - [Q(groups__subgroup=group.subgroup[:i]) - for i in range(1, len(group.subgroup) + 1)]) | \ - Q(groups__subgroup__isnull=True) - return self.get_queryset() \ - .filter(groups_criteria, - groups__mention=group.mention, - timetable=group.timetable, **criteria) \ + .filter(groups__in=Group.objects.get_parents(group), **criteria) \ .order_by("begin") def get_weeks(self, **criteria): -- cgit v1.2.1 From 912f3cca24da9d870aa191348fef901adcd55b7d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Wed, 1 Nov 2017 15:17:35 +0100 Subject: get_parents() sélectionne aussi les groupes enfants dont le sous-groupe commence par la même chaîne que celui du groupe passé en paramètre. Correction cosmétique du code. --- models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index c546737..c3118a3 100644 --- a/models.py +++ b/models.py @@ -71,7 +71,7 @@ class Timetable(SlugModel): class GroupManager(Manager): def get_parents(self, group): - groups_criteria = Q(subgroup__isnull=True) | \ + groups_criteria = Q(subgroup__isnull=True) | Q(subgroup__startswith=group.subgroup) | \ reduce(lambda x, y: x | y, [Q(subgroup=group.subgroup[:i]) for i in range(1, len(group.subgroup) + 1)]) @@ -80,7 +80,7 @@ class GroupManager(Manager): timetable=group.timetable) def get_relevant_groups(self, timetable, *args, **criteria): - sub = Group.objects.filter(timetable=timetable,mention=OuterRef("mention"), + sub = Group.objects.filter(timetable=timetable, mention=OuterRef("mention"), subgroup__startswith=OuterRef("subgroup")) \ .order_by().values("mention").annotate(c=Count("*")).values("c") -- cgit v1.2.1 From 9d364f627dc90f3a361cc9acbc2e91f64ee9edcf Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Wed, 1 Nov 2017 16:08:38 +0100 Subject: Utilisation de self.get_queryset() plutôt que Group.objects --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index c3118a3..cb975ab 100644 --- a/models.py +++ b/models.py @@ -80,7 +80,7 @@ class GroupManager(Manager): timetable=group.timetable) def get_relevant_groups(self, timetable, *args, **criteria): - sub = Group.objects.filter(timetable=timetable, mention=OuterRef("mention"), + sub = self.get_queryset().filter(timetable=timetable, mention=OuterRef("mention"), subgroup__startswith=OuterRef("subgroup")) \ .order_by().values("mention").annotate(c=Count("*")).values("c") -- cgit v1.2.1 From bb973abfbd566a0f019822453d06f8b0ef3f6dac Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Fri, 3 Nov 2017 17:40:11 +0100 Subject: Prise en compte des groupes qui n’ont pas de sous-groupe dans la liste des groupes pertinents --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index cb975ab..3af1c06 100644 --- a/models.py +++ b/models.py @@ -86,7 +86,7 @@ class GroupManager(Manager): return self.get_queryset().filter(*args, timetable=timetable, hidden=False, **criteria) \ .annotate(nbsub=Subquery(sub, output_field=models.IntegerField())) \ - .filter(nbsub=1).order_by("name") + .filter(Q(nbsub=1) | Q(nbsub__isnull=True)).order_by("name") class Group(models.Model): -- cgit v1.2.1