From d7034148c320d2fcb1748f09cb9afaa2746d9088 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Sun, 7 Mar 2021 18:07:42 +0100 Subject: [PATCH] Extend querysets for holidays and groups --- aleksis/apps/chronos/managers.py | 30 ++++++++++++++++++++++++++++-- aleksis/apps/chronos/models.py | 7 ++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index 8955a3f7..6d940948 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -1,10 +1,12 @@ from datetime import date, datetime, timedelta from enum import Enum -from typing import Optional, Union +from typing import Iterable, Optional, Union from django.contrib.sites.managers import CurrentSiteManager as _CurrentSiteManager from django.db import models -from django.db.models import Count, F, Q, QuerySet +from django.db.models import Count, ExpressionWrapper, F, Func, Q, QuerySet, Value +from django.db.models.fields import DateField +from django.db.models.functions import Concat from calendarweek import CalendarWeek @@ -298,6 +300,13 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): | Q(**{self._period_path + "lesson__groups__parent_groups": group}) ) + def filter_groups(self, groups: Iterable[Group]) -> QuerySet: + """Filter for all lessons one of the groups regularly attends.""" + return self.filter( + Q(**{self._period_path + "lesson__groups__in": groups}) + | Q(**{self._period_path + "lesson__groups__parent_groups__in": groups}) + ) + def filter_teacher(self, teacher: Union[Person, int]): """Filter for all lessons given by a certain teacher.""" qs1 = self.filter(**{self._period_path + "lesson__teachers": teacher}) @@ -589,6 +598,10 @@ class TimetableQuerySet(models.QuerySet): else: return self.filter(Q(groups=group) | Q(groups__parent_groups=group)) + def filter_groups(self, groups: Iterable[Group]) -> QuerySet: + """Filter for all objects one of the groups attends.""" + return self.filter(Q(groups__in=groups) | Q(groups__parent_groups__in=groups)).distinct() + def filter_teacher(self, teacher: Union[Person, int]): """Filter for all lessons given by a certain teacher.""" return self.filter(teachers=teacher) @@ -663,6 +676,19 @@ class ExtraLessonQuerySet(TimetableQuerySet, SchoolTermRelatedQuerySet, GroupByP """Filter all extra lessons on a day.""" return self.within_dates(day, day) + def annotate_day(self): + weekday_to_date = ExpressionWrapper( + Func( + Concat(F("year"), F("week")), + Value("IYYYIW"), + output_field=DateField(), + function="TO_DATE", + ) + + F("period__weekday"), + output_field=DateField(), + ) + return self.annotate(day=weekday_to_date) + class GroupPropertiesMixin: """Mixin for common group properties. diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 3dc0c6ba..6326f80a 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -3,7 +3,7 @@ from __future__ import annotations from datetime import date, datetime, time, timedelta -from typing import Dict, List, Optional, Tuple, Union +from typing import Dict, Iterator, List, Optional, Tuple, Union from django.core.exceptions import ValidationError from django.db import models @@ -685,6 +685,11 @@ class Holiday(ExtensibleModel): date_end = models.DateField(verbose_name=_("End date"), null=True) comments = models.TextField(verbose_name=_("Comments"), blank=True, null=True) + def get_days(self) -> Iterator[date]: + delta = self.date_end - self.date_start + for i in range(delta.days + 1): + yield self.date_start + timedelta(days=i) + @classmethod def on_day(cls, day: date) -> Optional["Holiday"]: holidays = cls.objects.on_day(day) -- GitLab