aboutsummaryrefslogtreecommitdiff
path: root/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'models.py')
-rw-r--r--models.py70
1 files changed, 33 insertions, 37 deletions
diff --git a/models.py b/models.py
index ec141a2..3af1c06 100644
--- a/models.py
+++ b/models.py
@@ -13,8 +13,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with celcatsanitizer. If not, see <http://www.gnu.org/licenses/>.
+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
@@ -67,17 +70,23 @@ 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_parents(self, group):
+ 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)])
+
+ return self.get_queryset().filter(groups_criteria, mention=group.mention,
+ timetable=group.timetable)
+
+ def get_relevant_groups(self, timetable, *args, **criteria):
+ sub = self.get_queryset().filter(timetable=timetable, mention=OuterRef("mention"),
+ subgroup__startswith=OuterRef("subgroup")) \
+ .order_by().values("mention").annotate(c=Count("*")).values("c")
- 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)
+ return self.get_queryset().filter(*args, timetable=timetable, hidden=False, **criteria) \
+ .annotate(nbsub=Subquery(sub, output_field=models.IntegerField())) \
+ .filter(Q(nbsub=1) | Q(nbsub__isnull=True)).order_by("name")
class Group(models.Model):
@@ -90,27 +99,26 @@ 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)
- 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)
- 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):
- 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 +128,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",),)
@@ -148,19 +156,8 @@ 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(*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):
@@ -175,8 +172,7 @@ class CourseManager(Manager):
class Course(models.Model):
objects = CourseManager()
- name = models.CharField(max_length=255, verbose_name="nom", default="Sans nom",
- null=True)
+ 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,