From c0f19d41c8dfb6d499defcfc63c273bbc8918584 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 9 Sep 2017 19:37:12 +0200 Subject: Génération automatique d’un slug pour les modèles Year et Timetable --- models.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 6bb9733..c263510 100644 --- a/models.py +++ b/models.py @@ -21,7 +21,19 @@ from django.utils.text import slugify from .utils import parse_group -class Year(models.Model): +class SlugModel(models.Model): + def save(self): + if not self.slug: + self.slug = slugify(self.name) + + super(SlugModel, self).save() + + + class Meta: + abstract = True + + +class Year(SlugModel): name = models.CharField(max_length=16, verbose_name="année") slug = models.SlugField(max_length=16, unique=True, default="") @@ -34,7 +46,7 @@ class Year(models.Model): verbose_name_plural = "années" -class Timetable(models.Model): +class Timetable(SlugModel): year = models.ForeignKey(Year, on_delete=models.CASCADE, verbose_name="année") name = models.CharField(max_length=64, verbose_name="nom") url = models.URLField(max_length=255, verbose_name="URL") -- cgit v1.2.1 From ddbaba1d2cc65215a8922f123ba580064b2cbe93 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 10 Sep 2017 12:49:09 +0200 Subject: Augmentation de la taille maximale des mentions --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index c263510..f223317 100644 --- a/models.py +++ b/models.py @@ -92,7 +92,7 @@ class Group(models.Model): celcat_name = models.CharField(max_length=255, verbose_name="nom dans Celcat") timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") - mention = models.CharField(max_length=32) + 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) -- cgit v1.2.1 From 77748ec01d1ef59d8436597a9b52675b309e1c4d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 24 Sep 2017 15:50:58 +0200 Subject: Ajout du champ last_update dans le modèle des cours --- models.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'models.py') diff --git a/models.py b/models.py index f223317..4a25b01 100644 --- a/models.py +++ b/models.py @@ -161,6 +161,8 @@ class Course(models.Model): begin = models.DateTimeField(verbose_name="début du cours", db_index=True) end = models.DateTimeField(verbose_name="fin du cours") + last_update = models.DateTimeField(verbose_name="dernière mise à jour") + def __str__(self): return self.name -- cgit v1.2.1 From e30b0c673cae607175c5bae6df6e87d8b100bdf3 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 24 Sep 2017 17:16:10 +0200 Subject: Suppression du modèle LastUpdate, utilisation du champ last_update à la place. --- models.py | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 4a25b01..5128c8a 100644 --- a/models.py +++ b/models.py @@ -62,24 +62,6 @@ class Timetable(SlugModel): verbose_name_plural = "emplois du temps" -class LastUpdate(models.Model): - timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") - week = models.IntegerField(verbose_name="semaine") - year = models.IntegerField(verbose_name="année") - date = models.DateTimeField(verbose_name="date de mise à jour") - - updated_at = models.DateTimeField(verbose_name="date de publication", null=True) - - def __str__(self): - return "{0}, semaine {1} de {2}".format(self.timetable, self.week, self.year) - - - class Meta: - unique_together = ("timetable", "week", "year",) - verbose_name = "dernière mise à jour" - verbose_name_plural = "dernières mises à jour" - - class GroupManager(Manager): def get_relevant_groups(self, *args, **criteria): return self.get_queryset().filter(*args, **criteria).annotate(children_count=Count("children")).filter(children_count=0) -- cgit v1.2.1 From dc5618c3b3af18a5f6e1d50844097c745317125a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 24 Sep 2017 17:36:40 +0200 Subject: Ajout de la date et de l’heure automatiquement lors de la création d’un cours --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index 5128c8a..e284c28 100644 --- a/models.py +++ b/models.py @@ -143,7 +143,7 @@ class Course(models.Model): begin = models.DateTimeField(verbose_name="début du cours", db_index=True) end = models.DateTimeField(verbose_name="fin du cours") - last_update = models.DateTimeField(verbose_name="dernière mise à jour") + last_update = models.DateTimeField(verbose_name="dernière mise à jour", auto_now_add=True) def __str__(self): return self.name -- cgit v1.2.1 From 020d204d393ebf8c7f2bc9f6848cd4892b278f70 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 24 Sep 2017 18:13:44 +0200 Subject: Récupération de la dernière mise à jour en filtrant par emploi du temps Changement de la valeur par défaut de last_update, qui posait problème get_week, pas get_weeks --- models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index e284c28..b1d6d27 100644 --- a/models.py +++ b/models.py @@ -16,6 +16,7 @@ from django.db import models from django.db.models import Count, Manager, Q from django.db.models.functions import ExtractWeek, ExtractYear +from django.utils import timezone from django.utils.text import slugify from .utils import parse_group @@ -143,7 +144,7 @@ class Course(models.Model): begin = models.DateTimeField(verbose_name="début du cours", db_index=True) end = models.DateTimeField(verbose_name="fin du cours") - last_update = models.DateTimeField(verbose_name="dernière mise à jour", auto_now_add=True) + last_update = models.DateTimeField(verbose_name="dernière mise à jour", default=timezone.now) def __str__(self): return self.name -- cgit v1.2.1 From 3d2fa6b15c58b775bc7e60e148f3a6bf1f2631d0 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 25 Sep 2017 15:50:02 +0200 Subject: Découpage des lignes dépassant les 80 caractères de long dans feeds.py et models.py --- models.py | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index b1d6d27..4be7ef5 100644 --- a/models.py +++ b/models.py @@ -48,7 +48,8 @@ class Year(SlugModel): class Timetable(SlugModel): - year = models.ForeignKey(Year, on_delete=models.CASCADE, verbose_name="année") + year = models.ForeignKey(Year, on_delete=models.CASCADE, + verbose_name="année") name = models.CharField(max_length=64, verbose_name="nom") url = models.URLField(max_length=255, verbose_name="URL") slug = models.SlugField(max_length=64, default="") @@ -65,26 +66,36 @@ class Timetable(SlugModel): class GroupManager(Manager): def get_relevant_groups(self, *args, **criteria): - return self.get_queryset().filter(*args, **criteria).annotate(children_count=Count("children")).filter(children_count=0) + return self.get_queryset().filter(*args, **criteria) \ + .annotate(children_count=Count("children")) \ + .filter(children_count=0) class Group(models.Model): objects = GroupManager() name = models.CharField(max_length=255, verbose_name="nom") - celcat_name = models.CharField(max_length=255, verbose_name="nom dans Celcat") - timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") + celcat_name = models.CharField(max_length=255, + verbose_name="nom dans Celcat") + timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, + verbose_name="emploi du temps") mention = models.CharField(max_length=128) - subgroup = models.CharField(max_length=1, verbose_name="sous-groupe", null=True) + 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") + parent = models.ForeignKey("self", verbose_name="groupe parent", null=True, + default=None, related_name="children") slug = models.SlugField(max_length=64, default="") def corresponds_to(self, timetable_id, mention, subgroup, td, tp): - 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) + 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) @property def group_info(self): @@ -104,7 +115,9 @@ class Group(models.Model): class Meta: index_together = ("mention", "subgroup", "td", "tp",) - unique_together = (("name", "timetable",), ("celcat_name", "timetable",), ("slug", "timetable",),) + unique_together = (("name", "timetable",), + ("celcat_name", "timetable",), + ("slug", "timetable",),) verbose_name = "groupe" verbose_name_plural = "groupes" @@ -124,18 +137,32 @@ class Room(models.Model): class CourseManager(Manager): def get_courses_for_group(self, group, **criteria): - return self.get_queryset().filter(Q(groups__td__isnull=True) | Q(groups__td=group.td), Q(groups__tp__isnull=True) | Q(groups__tp=group.tp), Q(groups__subgroup__isnull=True) | Q(groups__subgroup=group.subgroup), groups__mention=group.mention, timetable=group.timetable, **criteria).order_by("begin") + return self.get_queryset() \ + .filter(Q(groups__td__isnull=True) | Q(groups__td=group.td), + Q(groups__tp__isnull=True) | Q(groups__tp=group.tp), + Q(groups__subgroup__isnull=True) | \ + Q(groups__subgroup=group.subgroup), + groups__mention=group.mention, + timetable=group.timetable, **criteria) \ + .order_by("begin") def get_weeks(self, **criteria): - return self.get_queryset().filter(**criteria).order_by("groups__name", "year", "week").annotate(_=Count(("groups", "year", "week", "begin")), year=ExtractYear("begin"), week=ExtractWeek("begin")) + return self.get_queryset() \ + .filter(**criteria) \ + .order_by("groups__name", "year", "week") \ + .annotate(_=Count(("groups", "year", "week", "begin")), + year=ExtractYear("begin"), + week=ExtractWeek("begin")) class Course(models.Model): objects = CourseManager() name = models.CharField(max_length=255, verbose_name="nom", null=True) - type_ = models.CharField(name="type", max_length=255, verbose_name="type de cours", null=True) - timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") + type_ = models.CharField(name="type", max_length=255, + verbose_name="type de cours", null=True) + timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, + verbose_name="emploi du temps") notes = models.TextField(verbose_name="remarques", blank=True, null=True) groups = models.ManyToManyField(Group, verbose_name="groupes") @@ -144,7 +171,8 @@ class Course(models.Model): begin = models.DateTimeField(verbose_name="début du cours", db_index=True) end = models.DateTimeField(verbose_name="fin du cours") - last_update = models.DateTimeField(verbose_name="dernière mise à jour", default=timezone.now) + last_update = models.DateTimeField(verbose_name="dernière mise à jour", + default=timezone.now) def __str__(self): return self.name -- cgit v1.2.1 From a1231e340dbb9236f3804679360c0ab7895ae903 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 28 Sep 2017 21:57:54 +0200 Subject: Affichage seulement des groupes intéressants pour éviter des clics inutiles : Si les enfants d’un groupe ont eux-mêmes des enfants, on n’affiche pas ce groupe mais ces enfants. --- models.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'models.py') diff --git a/models.py b/models.py index 4be7ef5..0625e34 100644 --- a/models.py +++ b/models.py @@ -65,6 +65,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) \ + .order_by("name") + def get_relevant_groups(self, *args, **criteria): return self.get_queryset().filter(*args, **criteria) \ .annotate(children_count=Count("children")) \ -- cgit v1.2.1 From a30de7e84c7c7208f76178586befe5374cd1e02d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Fri, 29 Sep 2017 14:33:55 +0200 Subject: Affichage des cours des groupes enfants si le groupe demandé en possède --- models.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 0625e34..cca4df8 100644 --- a/models.py +++ b/models.py @@ -144,11 +144,17 @@ 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)) + return self.get_queryset() \ - .filter(Q(groups__td__isnull=True) | Q(groups__td=group.td), - Q(groups__tp__isnull=True) | Q(groups__tp=group.tp), - Q(groups__subgroup__isnull=True) | \ - Q(groups__subgroup=group.subgroup), + .filter(*groups_criteria, groups__mention=group.mention, timetable=group.timetable, **criteria) \ .order_by("begin") -- cgit v1.2.1 From e004bf8b70d1f8142e63748ea737e8c0ac8fcfda Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 1 Oct 2017 15:18:14 +0200 Subject: Changement de la valeur par défaut des cours --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index cca4df8..ae9265a 100644 --- a/models.py +++ b/models.py @@ -171,7 +171,7 @@ class CourseManager(Manager): class Course(models.Model): objects = CourseManager() - name = models.CharField(max_length=255, verbose_name="nom", null=True) + name = models.CharField(max_length=255, verbose_name="nom", default="Cours") 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 f0c61f1a3a26f8c76f43b21f7860d83041b7fe89 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 1 Oct 2017 16:44:53 +0200 Subject: Ajout d’une colonne pour stocker la date de dernière mise à jour --- models.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'models.py') diff --git a/models.py b/models.py index ae9265a..649368e 100644 --- a/models.py +++ b/models.py @@ -54,6 +54,8 @@ class Timetable(SlugModel): url = models.URLField(max_length=255, verbose_name="URL") slug = models.SlugField(max_length=64, default="") + last_update_date = models.DateTimeField(verbose_name="dernière mise à jour Celcat", null=True) + def __str__(self): return self.year.name + " " + self.name -- cgit v1.2.1 From 5d59112a9c7badc2cc0a48d1a8e33d48e1e6e719 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 1 Oct 2017 16:54:42 +0200 Subject: Ajout d’une colonne pour cacher un groupe dans la liste des groupes. Ajout d’actions personnalisées dans l’interface d’administration pour cacher et afficher plusieurs groupes à la fois. Filtrage des groupes cachés dans get_relevant_children() et get_relevant_groups(). --- models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'models.py') diff --git a/models.py b/models.py index 649368e..8bd2399 100644 --- a/models.py +++ b/models.py @@ -71,13 +71,13 @@ class GroupManager(Manager): 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) \ + .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) + .filter(children_count=0, hidden=False) class Group(models.Model): @@ -99,6 +99,8 @@ class Group(models.Model): slug = models.SlugField(max_length=64, default="") + hidden = models.BooleanField(verbose_name="caché", default=False) + def corresponds_to(self, timetable_id, mention, subgroup, td, tp): return self.timetable.id == timetable_id and \ self.mention.startswith(mention) and \ -- cgit v1.2.1 From 62c45f003e338440061c0d3e8356f2ab940e6edc Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 1 Oct 2017 18:58:34 +0200 Subject: Re-changement de la valeur par défaut du nom des cours --- models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'models.py') diff --git a/models.py b/models.py index 8bd2399..ec141a2 100644 --- a/models.py +++ b/models.py @@ -175,7 +175,8 @@ class CourseManager(Manager): class Course(models.Model): objects = CourseManager() - name = models.CharField(max_length=255, verbose_name="nom", default="Cours") + name = models.CharField(max_length=255, verbose_name="nom", default="Sans nom", + null=True) 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