diff --git a/aleksis/apps/chronos/forms.py b/aleksis/apps/chronos/forms.py index 3233cf8915326860c3d5370915c5ae37bd059a08..5b4803d7622844c7a29cdc6b7fb0f456adc3c316 100644 --- a/aleksis/apps/chronos/forms.py +++ b/aleksis/apps/chronos/forms.py @@ -26,4 +26,6 @@ class LessonSubstitutionForm(forms.ModelForm): } -AnnouncementForm.add_node_to_layout(Fieldset(_("Options for timetables"), "show_in_timetables")) +AnnouncementForm.add_node_to_layout( + Fieldset(_("Options for timetables"), "show_in_timetables") +) diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index 212a70f0ffaa00812d46f055857f0bddaaea3c32..d6c13a52f15216163f61ac79c4874f2e9829289f 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -121,7 +121,7 @@ class WeekQuerySetMixin: return self.annotate( _week=models.Value(week.week, models.IntegerField()), - _year=models.Value(week.year, models.IntegerField()) + _year=models.Value(week.year, models.IntegerField()), ) @@ -168,8 +168,10 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): def in_week(self, wanted_week: CalendarWeek): """Filter for all lessons within a calendar week.""" return self.within_dates( - wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), - wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), + wanted_week[0] + + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), + wanted_week[0] + + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), ).annotate_week(wanted_week) def on_day(self, day: date): @@ -201,7 +203,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): """Filter for all lessons a participant (student) attends.""" return self.filter( Q(**{self._period_path + "lesson__groups__members": person}) - | Q(**{self._period_path + "lesson__groups__parent_groups__members": person}) + | Q( + **{self._period_path + "lesson__groups__parent_groups__members": person} + ) ) def filter_group(self, group: Union[Group, int]): @@ -222,7 +226,10 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): """Filter for all lessons given by a certain teacher.""" qs1 = self.filter(**{self._period_path + "lesson__teachers": teacher}) qs2 = self.filter( - **{self._subst_path + "teachers": teacher, self._subst_path + "week": F("_week"),} + **{ + self._subst_path + "teachers": teacher, + self._subst_path + "week": F("_week"), + } ) return qs1.union(qs2) @@ -236,7 +243,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): return qs1.union(qs2) - def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + def filter_from_type( + self, type_: TimetableType, pk: int + ) -> Optional[models.QuerySet]: """Filter lesson data for a group, teacher or room by provided type.""" if type_ == TimetableType.GROUP: return self.filter_group(pk) @@ -276,7 +285,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): return lesson_periods - def next_lesson(self, reference: "LessonPeriod", offset: Optional[int] = 1) -> "LessonPeriod": + def next_lesson( + self, reference: "LessonPeriod", offset: Optional[int] = 1 + ) -> "LessonPeriod": """Get another lesson in an ordered set of lessons. By default, it returns the next lesson in the set. By passing the offset argument, @@ -324,7 +335,8 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet): selected substitutions (as substituted or substituting). """ return Person.objects.filter( - Q(lessons_as_teacher__in=self.affected_lessons()) | Q(lesson_substitutions__in=self) + Q(lessons_as_teacher__in=self.affected_lessons()) + | Q(lesson_substitutions__in=self) ).annotate(lessons_count=Count("lessons_as_teacher")) def affected_groups(self): @@ -365,13 +377,19 @@ class AbsenceQuerySet(SchoolTermRelatedQuerySet, DateRangeQuerySetMixin): """QuerySet with custom query methods for absences.""" def absent_teachers(self): - return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Person.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) def absent_groups(self): - return Group.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Group.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) def absent_rooms(self): - return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Person.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) class HolidayQuerySet(QuerySet, DateRangeQuerySetMixin): @@ -445,7 +463,9 @@ class TimetableQuerySet(models.QuerySet): else: return self.filter(room=room) - def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + def filter_from_type( + self, type_: TimetableType, pk: int + ) -> Optional[models.QuerySet]: """Filter data for a group, teacher or room by provided type.""" if type_ == TimetableType.GROUP: return self.filter_group(pk) diff --git a/aleksis/apps/chronos/migrations/0001_initial.py b/aleksis/apps/chronos/migrations/0001_initial.py index c27756636c30241178c68a29512b67bf8849b826..c1842ed902696312eca6b51a1bdbfaf5a71cbc8c 100644 --- a/aleksis/apps/chronos/migrations/0001_initial.py +++ b/aleksis/apps/chronos/migrations/0001_initial.py @@ -1,12 +1,14 @@ # Generated by Django 3.0.5 on 2020-05-04 14:16 -import aleksis.apps.chronos.managers -import calendarweek.calendarweek -import colorfield.fields import django.contrib.postgres.fields.jsonb import django.contrib.sites.managers -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models + +import calendarweek.calendarweek +import colorfield.fields + +import aleksis.apps.chronos.managers class Migration(migrations.Migration): @@ -14,449 +16,1188 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('core', '0001_initial'), - ('sites', '0002_alter_domain_unique'), + ("core", "0001_initial"), + ("sites", "0002_alter_domain_unique"), ] operations = [ migrations.CreateModel( - name='ChronosGlobalPermissions', + name="ChronosGlobalPermissions", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), ], options={ - 'permissions': (('view_all_timetables', 'Can view all timetables'), ('view_timetable_overview', 'Can view timetable overview'), ('view_lessons_day', 'Can view all lessons per day')), - 'managed': False, + "permissions": ( + ("view_all_timetables", "Can view all timetables"), + ("view_timetable_overview", "Can view timetable overview"), + ("view_lessons_day", "Can view all lessons per day"), + ), + "managed": False, }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='Break', + name="Break", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=255, verbose_name='Short name')), - ('name', models.CharField(max_length=255, verbose_name='Long name')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField(max_length=255, verbose_name="Short name"), + ), + ("name", models.CharField(max_length=255, verbose_name="Long name")), ], options={ - 'verbose_name': 'Break', - 'verbose_name_plural': 'Breaks', - 'ordering': ['after_period'], + "verbose_name": "Break", + "verbose_name_plural": "Breaks", + "ordering": ["after_period"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='Lesson', + name="Lesson", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date_start', models.DateField(null=True, verbose_name='Start date')), - ('date_end', models.DateField(null=True, verbose_name='End date')), - ('groups', models.ManyToManyField(related_name='lessons', to='core.Group', verbose_name='Groups')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date_start", models.DateField(null=True, verbose_name="Start date")), + ("date_end", models.DateField(null=True, verbose_name="End date")), + ( + "groups", + models.ManyToManyField( + related_name="lessons", to="core.Group", verbose_name="Groups" + ), + ), ], options={ - 'verbose_name': 'Lesson', - 'verbose_name_plural': 'Lessons', - 'ordering': ['date_start', 'subject'], + "verbose_name": "Lesson", + "verbose_name_plural": "Lessons", + "ordering": ["date_start", "subject"], }, - bases=(models.Model, aleksis.apps.chronos.managers.GroupPropertiesMixin, aleksis.apps.chronos.managers.TeacherPropertiesMixin), - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + bases=( + models.Model, + aleksis.apps.chronos.managers.GroupPropertiesMixin, + aleksis.apps.chronos.managers.TeacherPropertiesMixin, + ), + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='LessonPeriod', + name="LessonPeriod", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lesson_periods', to='chronos.Lesson', verbose_name='Lesson')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "lesson", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="lesson_periods", + to="chronos.Lesson", + verbose_name="Lesson", + ), + ), ], options={ - 'verbose_name': 'Lesson period', - 'verbose_name_plural': 'Lesson periods', - 'ordering': ['lesson__date_start', 'period__weekday', 'period__period', 'lesson__subject'], + "verbose_name": "Lesson period", + "verbose_name_plural": "Lesson periods", + "ordering": [ + "lesson__date_start", + "period__weekday", + "period__period", + "lesson__subject", + ], }, ), migrations.CreateModel( - name='Supervision', + name="Supervision", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), ], options={ - 'verbose_name': 'Supervision', - 'verbose_name_plural': 'Supervisions', - 'ordering': ['area', 'break_item'], + "verbose_name": "Supervision", + "verbose_name_plural": "Supervisions", + "ordering": ["area", "break_item"], }, ), migrations.CreateModel( - name='TimetableWidget', - fields=[ - ], + name="TimetableWidget", + fields=[], options={ - 'verbose_name': 'Timetable widget', - 'verbose_name_plural': 'Timetable widgets', - 'proxy': True, - 'indexes': [], - 'constraints': [], + "verbose_name": "Timetable widget", + "verbose_name_plural": "Timetable widgets", + "proxy": True, + "indexes": [], + "constraints": [], }, - bases=('core.dashboardwidget',), + bases=("core.dashboardwidget",), ), migrations.CreateModel( - name='TimePeriod', + name="TimePeriod", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('weekday', models.PositiveSmallIntegerField(choices=[(0, 'Monday'), (1, 'Tuesday'), (2, 'Wednesday'), (3, 'Thursday'), (4, 'Friday'), (5, 'Saturday'), (6, 'Sunday')], verbose_name='Week day')), - ('period', models.PositiveSmallIntegerField(verbose_name='Number of period')), - ('time_start', models.TimeField(verbose_name='Start time')), - ('time_end', models.TimeField(verbose_name='End time')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "weekday", + models.PositiveSmallIntegerField( + choices=[ + (0, "Monday"), + (1, "Tuesday"), + (2, "Wednesday"), + (3, "Thursday"), + (4, "Friday"), + (5, "Saturday"), + (6, "Sunday"), + ], + verbose_name="Week day", + ), + ), + ( + "period", + models.PositiveSmallIntegerField(verbose_name="Number of period"), + ), + ("time_start", models.TimeField(verbose_name="Start time")), + ("time_end", models.TimeField(verbose_name="End time")), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Time period', - 'verbose_name_plural': 'Time periods', - 'ordering': ['weekday', 'period'], + "verbose_name": "Time period", + "verbose_name_plural": "Time periods", + "ordering": ["weekday", "period"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='SupervisionSubstitution', + name="SupervisionSubstitution", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date', models.DateField(verbose_name='Date')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('supervision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='substitutions', to='chronos.Supervision', verbose_name='Supervision')), - ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='substituted_supervisions', to='core.Person', verbose_name='Teacher')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date", models.DateField(verbose_name="Date")), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), + ( + "supervision", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="substitutions", + to="chronos.Supervision", + verbose_name="Supervision", + ), + ), + ( + "teacher", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="substituted_supervisions", + to="core.Person", + verbose_name="Teacher", + ), + ), ], options={ - 'verbose_name': 'Supervision substitution', - 'verbose_name_plural': 'Supervision substitutions', - 'ordering': ['date', 'supervision'], + "verbose_name": "Supervision substitution", + "verbose_name_plural": "Supervision substitutions", + "ordering": ["date", "supervision"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='SupervisionArea', + name="SupervisionArea", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=255, verbose_name='Short name')), - ('name', models.CharField(max_length=255, verbose_name='Long name')), - ('colour_fg', colorfield.fields.ColorField(default='#000000', max_length=18)), - ('colour_bg', colorfield.fields.ColorField(default='#FFFFFF', max_length=18)), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField(max_length=255, verbose_name="Short name"), + ), + ("name", models.CharField(max_length=255, verbose_name="Long name")), + ( + "colour_fg", + colorfield.fields.ColorField(default="#000000", max_length=18), + ), + ( + "colour_bg", + colorfield.fields.ColorField(default="#FFFFFF", max_length=18), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Supervision area', - 'verbose_name_plural': 'Supervision areas', - 'ordering': ['name'], + "verbose_name": "Supervision area", + "verbose_name_plural": "Supervision areas", + "ordering": ["name"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.AddField( - model_name='supervision', - name='area', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', to='chronos.SupervisionArea', verbose_name='Supervision area'), + model_name="supervision", + name="area", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="chronos.SupervisionArea", + verbose_name="Supervision area", + ), ), migrations.AddField( - model_name='supervision', - name='break_item', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', to='chronos.Break', verbose_name='Break'), + model_name="supervision", + name="break_item", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="chronos.Break", + verbose_name="Break", + ), ), migrations.AddField( - model_name='supervision', - name='site', - field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + model_name="supervision", + name="site", + field=models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), ), migrations.AddField( - model_name='supervision', - name='teacher', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', to='core.Person', verbose_name='Teacher'), + model_name="supervision", + name="teacher", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="core.Person", + verbose_name="Teacher", + ), ), migrations.CreateModel( - name='Subject', + name="Subject", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=255, unique=True, verbose_name='Short name')), - ('name', models.CharField(max_length=255, unique=True, verbose_name='Long name')), - ('colour_fg', colorfield.fields.ColorField(blank=True, default='', max_length=18, verbose_name='Foreground colour')), - ('colour_bg', colorfield.fields.ColorField(blank=True, default='', max_length=18, verbose_name='Background colour')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField( + max_length=255, unique=True, verbose_name="Short name" + ), + ), + ( + "name", + models.CharField( + max_length=255, unique=True, verbose_name="Long name" + ), + ), + ( + "colour_fg", + colorfield.fields.ColorField( + blank=True, + default="", + max_length=18, + verbose_name="Foreground colour", + ), + ), + ( + "colour_bg", + colorfield.fields.ColorField( + blank=True, + default="", + max_length=18, + verbose_name="Background colour", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Subject', - 'verbose_name_plural': 'Subjects', - 'ordering': ['name', 'short_name'], + "verbose_name": "Subject", + "verbose_name_plural": "Subjects", + "ordering": ["name", "short_name"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='Room', + name="Room", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=255, unique=True, verbose_name='Short name')), - ('name', models.CharField(max_length=255, verbose_name='Long name')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField( + max_length=255, unique=True, verbose_name="Short name" + ), + ), + ("name", models.CharField(max_length=255, verbose_name="Long name")), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Room', - 'verbose_name_plural': 'Rooms', - 'ordering': ['name', 'short_name'], + "verbose_name": "Room", + "verbose_name_plural": "Rooms", + "ordering": ["name", "short_name"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='LessonSubstitution', + name="LessonSubstitution", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('week', models.IntegerField(default=calendarweek.calendarweek.CalendarWeek.current_week, verbose_name='Week')), - ('cancelled', models.BooleanField(default=False, verbose_name='Cancelled?')), - ('cancelled_for_teachers', models.BooleanField(default=False, verbose_name='Cancelled for teachers?')), - ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), - ('lesson_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='substitutions', to='chronos.LessonPeriod', verbose_name='Lesson period')), - ('room', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='chronos.Room', verbose_name='Room')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='lesson_substitutions', to='chronos.Subject', verbose_name='Subject')), - ('teachers', models.ManyToManyField(blank=True, related_name='lesson_substitutions', to='core.Person', verbose_name='Teachers')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "week", + models.IntegerField( + default=calendarweek.calendarweek.CalendarWeek.current_week, + verbose_name="Week", + ), + ), + ( + "cancelled", + models.BooleanField(default=False, verbose_name="Cancelled?"), + ), + ( + "cancelled_for_teachers", + models.BooleanField( + default=False, verbose_name="Cancelled for teachers?" + ), + ), + ( + "comment", + models.TextField(blank=True, null=True, verbose_name="Comment"), + ), + ( + "lesson_period", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="substitutions", + to="chronos.LessonPeriod", + verbose_name="Lesson period", + ), + ), + ( + "room", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="chronos.Room", + verbose_name="Room", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), + ( + "subject", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="lesson_substitutions", + to="chronos.Subject", + verbose_name="Subject", + ), + ), + ( + "teachers", + models.ManyToManyField( + blank=True, + related_name="lesson_substitutions", + to="core.Person", + verbose_name="Teachers", + ), + ), ], options={ - 'verbose_name': 'Lesson substitution', - 'verbose_name_plural': 'Lesson substitutions', - 'ordering': ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period'], + "verbose_name": "Lesson substitution", + "verbose_name_plural": "Lesson substitutions", + "ordering": [ + "lesson_period__lesson__date_start", + "week", + "lesson_period__period__weekday", + "lesson_period__period__period", + ], }, ), migrations.AddField( - model_name='lessonperiod', - name='period', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lesson_periods', to='chronos.TimePeriod', verbose_name='Time period'), + model_name="lessonperiod", + name="period", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="lesson_periods", + to="chronos.TimePeriod", + verbose_name="Time period", + ), ), migrations.AddField( - model_name='lessonperiod', - name='room', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='lesson_periods', to='chronos.Room', verbose_name='Room'), + model_name="lessonperiod", + name="room", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="lesson_periods", + to="chronos.Room", + verbose_name="Room", + ), ), migrations.AddField( - model_name='lessonperiod', - name='site', - field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + model_name="lessonperiod", + name="site", + field=models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), ), migrations.AddField( - model_name='lesson', - name='periods', - field=models.ManyToManyField(related_name='lessons', through='chronos.LessonPeriod', to='chronos.TimePeriod', verbose_name='Periods'), + model_name="lesson", + name="periods", + field=models.ManyToManyField( + related_name="lessons", + through="chronos.LessonPeriod", + to="chronos.TimePeriod", + verbose_name="Periods", + ), ), migrations.AddField( - model_name='lesson', - name='site', - field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + model_name="lesson", + name="site", + field=models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), ), migrations.AddField( - model_name='lesson', - name='subject', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lessons', to='chronos.Subject', verbose_name='Subject'), + model_name="lesson", + name="subject", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="lessons", + to="chronos.Subject", + verbose_name="Subject", + ), ), migrations.AddField( - model_name='lesson', - name='teachers', - field=models.ManyToManyField(related_name='lessons_as_teacher', to='core.Person', verbose_name='Teachers'), + model_name="lesson", + name="teachers", + field=models.ManyToManyField( + related_name="lessons_as_teacher", + to="core.Person", + verbose_name="Teachers", + ), ), migrations.CreateModel( - name='Holiday', + name="Holiday", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('title', models.CharField(max_length=255, verbose_name='Title')), - ('date_start', models.DateField(null=True, verbose_name='Start date')), - ('date_end', models.DateField(null=True, verbose_name='End date')), - ('comments', models.TextField(blank=True, null=True, verbose_name='Comments')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("title", models.CharField(max_length=255, verbose_name="Title")), + ("date_start", models.DateField(null=True, verbose_name="Start date")), + ("date_end", models.DateField(null=True, verbose_name="End date")), + ( + "comments", + models.TextField(blank=True, null=True, verbose_name="Comments"), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Holiday', - 'verbose_name_plural': 'Holidays', - 'ordering': ['date_start'], + "verbose_name": "Holiday", + "verbose_name_plural": "Holidays", + "ordering": ["date_start"], }, ), migrations.CreateModel( - name='ExtraLesson', + name="ExtraLesson", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('week', models.IntegerField(default=calendarweek.calendarweek.CalendarWeek.current_week, verbose_name='Week')), - ('comment', models.CharField(blank=True, max_length=255, null=True, verbose_name='Comment')), - ('groups', models.ManyToManyField(related_name='extra_lessons', to='core.Group', verbose_name='Groups')), - ('period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.TimePeriod', verbose_name='Time period')), - ('room', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.Room', verbose_name='Room')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.Subject', verbose_name='Subject')), - ('teachers', models.ManyToManyField(related_name='extra_lessons_as_teacher', to='core.Person', verbose_name='Teachers')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "week", + models.IntegerField( + default=calendarweek.calendarweek.CalendarWeek.current_week, + verbose_name="Week", + ), + ), + ( + "comment", + models.CharField( + blank=True, max_length=255, null=True, verbose_name="Comment" + ), + ), + ( + "groups", + models.ManyToManyField( + related_name="extra_lessons", + to="core.Group", + verbose_name="Groups", + ), + ), + ( + "period", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.TimePeriod", + verbose_name="Time period", + ), + ), + ( + "room", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.Room", + verbose_name="Room", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), + ( + "subject", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.Subject", + verbose_name="Subject", + ), + ), + ( + "teachers", + models.ManyToManyField( + related_name="extra_lessons_as_teacher", + to="core.Person", + verbose_name="Teachers", + ), + ), ], options={ - 'verbose_name': 'Extra lesson', - 'verbose_name_plural': 'Extra lessons', + "verbose_name": "Extra lesson", + "verbose_name_plural": "Extra lessons", }, bases=(models.Model, aleksis.apps.chronos.managers.GroupPropertiesMixin), ), migrations.CreateModel( - name='Exam', + name="Exam", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date', models.DateField(null=True, verbose_name='Date of exam')), - ('title', models.CharField(max_length=255, verbose_name='Title')), - ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), - ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exams', to='chronos.Lesson', verbose_name='Lesson')), - ('period_from', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Start period')), - ('period_to', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='End period')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date", models.DateField(null=True, verbose_name="Date of exam")), + ("title", models.CharField(max_length=255, verbose_name="Title")), + ( + "comment", + models.TextField(blank=True, null=True, verbose_name="Comment"), + ), + ( + "lesson", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="exams", + to="chronos.Lesson", + verbose_name="Lesson", + ), + ), + ( + "period_from", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Start period", + ), + ), + ( + "period_to", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="End period", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Exam', - 'verbose_name_plural': 'Exams', - 'ordering': ['date'], + "verbose_name": "Exam", + "verbose_name_plural": "Exams", + "ordering": ["date"], }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='Event', + name="Event", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('title', models.CharField(blank=True, max_length=255, null=True, verbose_name='Title')), - ('date_start', models.DateField(null=True, verbose_name='Start date')), - ('date_end', models.DateField(null=True, verbose_name='End date')), - ('groups', models.ManyToManyField(related_name='events', to='core.Group', verbose_name='Groups')), - ('period_from', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Start time period')), - ('period_to', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='End time period')), - ('rooms', models.ManyToManyField(related_name='events', to='chronos.Room', verbose_name='Rooms')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('teachers', models.ManyToManyField(related_name='events', to='core.Person', verbose_name='Teachers')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "title", + models.CharField( + blank=True, max_length=255, null=True, verbose_name="Title" + ), + ), + ("date_start", models.DateField(null=True, verbose_name="Start date")), + ("date_end", models.DateField(null=True, verbose_name="End date")), + ( + "groups", + models.ManyToManyField( + related_name="events", to="core.Group", verbose_name="Groups" + ), + ), + ( + "period_from", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Start time period", + ), + ), + ( + "period_to", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="End time period", + ), + ), + ( + "rooms", + models.ManyToManyField( + related_name="events", to="chronos.Room", verbose_name="Rooms" + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), + ( + "teachers", + models.ManyToManyField( + related_name="events", to="core.Person", verbose_name="Teachers" + ), + ), ], options={ - 'verbose_name': 'Event', - 'verbose_name_plural': 'Events', - 'ordering': ['date_start'], + "verbose_name": "Event", + "verbose_name_plural": "Events", + "ordering": ["date_start"], }, - bases=(models.Model, aleksis.apps.chronos.managers.GroupPropertiesMixin, aleksis.apps.chronos.managers.TeacherPropertiesMixin), + bases=( + models.Model, + aleksis.apps.chronos.managers.GroupPropertiesMixin, + aleksis.apps.chronos.managers.TeacherPropertiesMixin, + ), ), migrations.AddField( - model_name='break', - name='after_period', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='break_after', to='chronos.TimePeriod', verbose_name='Time period after break starts'), + model_name="break", + name="after_period", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="break_after", + to="chronos.TimePeriod", + verbose_name="Time period after break starts", + ), ), migrations.AddField( - model_name='break', - name='before_period', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='break_before', to='chronos.TimePeriod', verbose_name='Time period before break ends'), + model_name="break", + name="before_period", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="break_before", + to="chronos.TimePeriod", + verbose_name="Time period before break ends", + ), ), migrations.AddField( - model_name='break', - name='site', - field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + model_name="break", + name="site", + field=models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), ), migrations.CreateModel( - name='AbsenceReason', + name="AbsenceReason", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=255, verbose_name='Short name')), - ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Name')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField(max_length=255, verbose_name="Short name"), + ), + ( + "name", + models.CharField( + blank=True, max_length=255, null=True, verbose_name="Name" + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), ], options={ - 'verbose_name': 'Absence reason', - 'verbose_name_plural': 'Absence reasons', + "verbose_name": "Absence reason", + "verbose_name_plural": "Absence reasons", }, - managers=[ - ('objects', django.contrib.sites.managers.CurrentSiteManager()), - ], + managers=[("objects", django.contrib.sites.managers.CurrentSiteManager()),], ), migrations.CreateModel( - name='Absence', + name="Absence", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date_start', models.DateField(null=True, verbose_name='Start date')), - ('date_end', models.DateField(null=True, verbose_name='End date')), - ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), - ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='core.Group', verbose_name='Group')), - ('period_from', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Start period')), - ('period_to', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='End period')), - ('reason', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='absences', to='chronos.AbsenceReason', verbose_name='Absence reason')), - ('room', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='chronos.Room', verbose_name='Room')), - ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('teacher', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='core.Person', verbose_name='Teacher')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date_start", models.DateField(null=True, verbose_name="Start date")), + ("date_end", models.DateField(null=True, verbose_name="End date")), + ( + "comment", + models.TextField(blank=True, null=True, verbose_name="Comment"), + ), + ( + "group", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="core.Group", + verbose_name="Group", + ), + ), + ( + "period_from", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Start period", + ), + ), + ( + "period_to", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="End period", + ), + ), + ( + "reason", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="absences", + to="chronos.AbsenceReason", + verbose_name="Absence reason", + ), + ), + ( + "room", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="chronos.Room", + verbose_name="Room", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), + ), + ( + "teacher", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="core.Person", + verbose_name="Teacher", + ), + ), ], options={ - 'verbose_name': 'Absence', - 'verbose_name_plural': 'Absences', - 'ordering': ['date_start'], + "verbose_name": "Absence", + "verbose_name_plural": "Absences", + "ordering": ["date_start"], }, ), migrations.AddIndex( - model_name='timeperiod', - index=models.Index(fields=['time_start', 'time_end'], name='chronos_tim_time_st_491e4c_idx'), + model_name="timeperiod", + index=models.Index( + fields=["time_start", "time_end"], name="chronos_tim_time_st_491e4c_idx" + ), ), migrations.AlterUniqueTogether( - name='timeperiod', - unique_together={('weekday', 'period')}, + name="timeperiod", unique_together={("weekday", "period")}, ), migrations.AddConstraint( - model_name='lessonsubstitution', - constraint=models.CheckConstraint(check=models.Q(('cancelled', True), ('subject__isnull', False), _negated=True), name='either_substituted_or_cancelled'), + model_name="lessonsubstitution", + constraint=models.CheckConstraint( + check=models.Q( + ("cancelled", True), ("subject__isnull", False), _negated=True + ), + name="either_substituted_or_cancelled", + ), ), migrations.AlterUniqueTogether( - name='lessonsubstitution', - unique_together={('lesson_period', 'week')}, + name="lessonsubstitution", unique_together={("lesson_period", "week")}, ), migrations.AddIndex( - model_name='lessonperiod', - index=models.Index(fields=['lesson', 'period'], name='chronos_les_lesson__05250e_idx'), + model_name="lessonperiod", + index=models.Index( + fields=["lesson", "period"], name="chronos_les_lesson__05250e_idx" + ), ), migrations.AddIndex( - model_name='lesson', - index=models.Index(fields=['date_start', 'date_end'], name='chronos_les_date_st_5ecc62_idx'), + model_name="lesson", + index=models.Index( + fields=["date_start", "date_end"], name="chronos_les_date_st_5ecc62_idx" + ), ), migrations.AddIndex( - model_name='holiday', - index=models.Index(fields=['date_start', 'date_end'], name='chronos_hol_date_st_a47004_idx'), + model_name="holiday", + index=models.Index( + fields=["date_start", "date_end"], name="chronos_hol_date_st_a47004_idx" + ), ), migrations.AddIndex( - model_name='exam', - index=models.Index(fields=['date'], name='chronos_exa_date_5ba442_idx'), + model_name="exam", + index=models.Index(fields=["date"], name="chronos_exa_date_5ba442_idx"), ), migrations.AddIndex( - model_name='event', - index=models.Index(fields=['period_from', 'period_to', 'date_start', 'date_end'], name='chronos_eve_period__c7ec33_idx'), + model_name="event", + index=models.Index( + fields=["period_from", "period_to", "date_start", "date_end"], + name="chronos_eve_period__c7ec33_idx", + ), ), migrations.AddIndex( - model_name='break', - index=models.Index(fields=['after_period', 'before_period'], name='chronos_bre_after_p_0f28d3_idx'), + model_name="break", + index=models.Index( + fields=["after_period", "before_period"], + name="chronos_bre_after_p_0f28d3_idx", + ), ), migrations.AddIndex( - model_name='absence', - index=models.Index(fields=['date_start', 'date_end'], name='chronos_abs_date_st_337ff5_idx'), + model_name="absence", + index=models.Index( + fields=["date_start", "date_end"], name="chronos_abs_date_st_337ff5_idx" + ), ), ] diff --git a/aleksis/apps/chronos/model_extensions.py b/aleksis/apps/chronos/model_extensions.py index c98235fc05838aff737c2076dc29d0a68a9c51ad..3a288a299651296dd7c1e78a941f6982fe48d616 100644 --- a/aleksis/apps/chronos/model_extensions.py +++ b/aleksis/apps/chronos/model_extensions.py @@ -86,7 +86,9 @@ def for_timetables(cls): Announcement.class_method(for_timetables) Announcement.field( - show_in_timetables=BooleanField(verbose_name=_("Show announcement in timetable views?")) + show_in_timetables=BooleanField( + verbose_name=_("Show announcement in timetable views?") + ) ) Group.foreign_key("subject", Subject, related_name="groups") diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 2883803533f495aa4cd68a9dc505ed9a8d9c6b58..0331ff3c7515e478686e0e2daeb5e14a9d9c84bd 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -116,7 +116,9 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): WEEKDAY_CHOICES = list(enumerate(i18n_day_names_lazy())) WEEKDAY_CHOICES_SHORT = list(enumerate(i18n_day_abbrs_lazy())) - weekday = models.PositiveSmallIntegerField(verbose_name=_("Week day"), choices=WEEKDAY_CHOICES) + weekday = models.PositiveSmallIntegerField( + verbose_name=_("Week day"), choices=WEEKDAY_CHOICES + ) period = models.PositiveSmallIntegerField(verbose_name=_("Number of period")) time_start = models.TimeField(verbose_name=_("Start time")) @@ -147,12 +149,16 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): return wanted_week[self.weekday] - def get_datetime_start(self, week: Optional[Union[CalendarWeek, int]] = None) -> datetime: + def get_datetime_start( + self, week: Optional[Union[CalendarWeek, int]] = None + ) -> datetime: """Get datetime of lesson start in a specific week.""" day = self.get_date(week) return datetime.combine(day, self.time_start) - def get_datetime_end(self, week: Optional[Union[CalendarWeek, int]] = None) -> datetime: + def get_datetime_end( + self, week: Optional[Union[CalendarWeek, int]] = None + ) -> datetime: """Get datetime of lesson end in a specific week.""" day = self.get_date(week) return datetime.combine(day, self.time_end) @@ -199,6 +205,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): @classproperty def period_min(cls) -> int: + return ( cls.objects.for_current_or_all() .aggregate(period__min=Coalesce(Min("period"), 1)) @@ -254,7 +261,9 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): class Subject(ExtensibleModel): - short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True) + short_name = models.CharField( + verbose_name=_("Short name"), max_length=255, unique=True + ) name = models.CharField(verbose_name=_("Long name"), max_length=255, unique=True) colour_fg = ColorField(verbose_name=_("Foreground colour"), blank=True) @@ -270,7 +279,9 @@ class Subject(ExtensibleModel): class Room(ExtensibleModel): - short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True) + short_name = models.CharField( + verbose_name=_("Short name"), max_length=255, unique=True + ) name = models.CharField(verbose_name=_("Long name"), max_length=255) def __str__(self) -> str: @@ -286,15 +297,23 @@ class Lesson( ValidityRangeRelatedExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin ): subject = models.ForeignKey( - "Subject", on_delete=models.CASCADE, related_name="lessons", verbose_name=_("Subject"), + "Subject", + on_delete=models.CASCADE, + related_name="lessons", + verbose_name=_("Subject"), ) teachers = models.ManyToManyField( "core.Person", related_name="lessons_as_teacher", verbose_name=_("Teachers") ) periods = models.ManyToManyField( - "TimePeriod", related_name="lessons", through="LessonPeriod", verbose_name=_("Periods"), + "TimePeriod", + related_name="lessons", + through="LessonPeriod", + verbose_name=_("Periods"), + ) + groups = models.ManyToManyField( + "core.Group", related_name="lessons", verbose_name=_("Groups") ) - groups = models.ManyToManyField("core.Group", related_name="lessons", verbose_name=_("Groups")) def get_year(self, week: int) -> int: year = self.validity.date_start.year @@ -319,7 +338,9 @@ class Lesson( class LessonSubstitution(ExtensibleModel): objects = LessonSubstitutionManager.from_queryset(LessonSubstitutionQuerySet)() - week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week) + week = models.IntegerField( + verbose_name=_("Week"), default=CalendarWeek.current_week + ) lesson_period = models.ForeignKey( "LessonPeriod", models.CASCADE, "substitutions", verbose_name=_("Lesson period") @@ -334,9 +355,14 @@ class LessonSubstitution(ExtensibleModel): verbose_name=_("Subject"), ) teachers = models.ManyToManyField( - "core.Person", related_name="lesson_substitutions", blank=True, verbose_name=_("Teachers"), + "core.Person", + related_name="lesson_substitutions", + blank=True, + verbose_name=_("Teachers"), + ) + room = models.ForeignKey( + "Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room") ) - room = models.ForeignKey("Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room")) cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled?")) cancelled_for_teachers = models.BooleanField( @@ -347,7 +373,9 @@ class LessonSubstitution(ExtensibleModel): def clean(self) -> None: if self.subject and self.cancelled: - raise ValidationError(_("Lessons can only be either substituted or cancelled.")) + raise ValidationError( + _("Lessons can only be either substituted or cancelled.") + ) @property def date(self): @@ -381,14 +409,24 @@ class LessonPeriod(ExtensibleModel): objects = LessonPeriodManager.from_queryset(LessonPeriodQuerySet)() lesson = models.ForeignKey( - "Lesson", models.CASCADE, related_name="lesson_periods", verbose_name=_("Lesson"), + "Lesson", + models.CASCADE, + related_name="lesson_periods", + verbose_name=_("Lesson"), ) period = models.ForeignKey( - "TimePeriod", models.CASCADE, related_name="lesson_periods", verbose_name=_("Time period"), + "TimePeriod", + models.CASCADE, + related_name="lesson_periods", + verbose_name=_("Time period"), ) room = models.ForeignKey( - "Room", models.CASCADE, null=True, related_name="lesson_periods", verbose_name=_("Room"), + "Room", + models.CASCADE, + null=True, + related_name="lesson_periods", + verbose_name=_("Room"), ) def get_substitution(self, week: Optional[int] = None) -> LessonSubstitution: @@ -478,7 +516,9 @@ class TimetableWidget(DashboardWidget): request = get_request() context = {"has_plan": True} - wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) if has_person(request.user): person = request.user.person @@ -512,7 +552,9 @@ class TimetableWidget(DashboardWidget): class AbsenceReason(ExtensibleModel): short_name = models.CharField(verbose_name=_("Short name"), max_length=255) - name = models.CharField(verbose_name=_("Name"), blank=True, null=True, max_length=255) + name = models.CharField( + verbose_name=_("Name"), blank=True, null=True, max_length=255 + ) def __str__(self): if self.name: @@ -599,7 +641,10 @@ class Absence(SchoolTermRelatedExtensibleModel): class Exam(SchoolTermRelatedExtensibleModel): lesson = models.ForeignKey( - "Lesson", on_delete=models.CASCADE, related_name="exams", verbose_name=_("Lesson"), + "Lesson", + on_delete=models.CASCADE, + related_name="exams", + verbose_name=_("Lesson"), ) date = models.DateField(verbose_name=_("Date of exam"), null=True) @@ -704,15 +749,27 @@ class Break(ValidityRangeRelatedExtensibleModel): @property def weekday(self): - return self.after_period.weekday if self.after_period else self.before_period.weekday + return ( + self.after_period.weekday + if self.after_period + else self.before_period.weekday + ) @property def after_period_number(self): - return self.after_period.period if self.after_period else self.before_period.period - 1 + return ( + self.after_period.period + if self.after_period + else self.before_period.period - 1 + ) @property def before_period_number(self): - return self.before_period.period if self.before_period else self.after_period.period + 1 + return ( + self.before_period.period + if self.before_period + else self.after_period.period + 1 + ) @property def time_start(self): @@ -753,10 +810,15 @@ class Supervision(ValidityRangeRelatedExtensibleModel): Break, models.CASCADE, verbose_name=_("Break"), related_name="supervisions" ) teacher = models.ForeignKey( - "core.Person", models.CASCADE, related_name="supervisions", verbose_name=_("Teacher"), + "core.Person", + models.CASCADE, + related_name="supervisions", + verbose_name=_("Teacher"), ) - def get_substitution(self, week: Optional[int] = None) -> Optional[SupervisionSubstitution]: + def get_substitution( + self, week: Optional[int] = None + ) -> Optional[SupervisionSubstitution]: wanted_week = week or getattr(self, "_week", None) or CalendarWeek().week wanted_week = CalendarWeek(week=wanted_week) # We iterate over all substitutions because this can make use of @@ -784,7 +846,10 @@ class Supervision(ValidityRangeRelatedExtensibleModel): class SupervisionSubstitution(ExtensibleModel): date = models.DateField(verbose_name=_("Date")) supervision = models.ForeignKey( - Supervision, models.CASCADE, verbose_name=_("Supervision"), related_name="substitutions", + Supervision, + models.CASCADE, + verbose_name=_("Supervision"), + related_name="substitutions", ) teacher = models.ForeignKey( "core.Person", @@ -813,7 +878,9 @@ class Event( objects = CurrentSiteManager.from_queryset(EventQuerySet)() - title = models.CharField(verbose_name=_("Title"), max_length=255, blank=True, null=True) + title = models.CharField( + verbose_name=_("Title"), max_length=255, blank=True, null=True + ) date_start = models.DateField(verbose_name=_("Start date"), null=True) date_end = models.DateField(verbose_name=_("End date"), null=True) @@ -825,11 +892,18 @@ class Event( related_name="+", ) period_to = models.ForeignKey( - "TimePeriod", on_delete=models.CASCADE, verbose_name=_("End time period"), related_name="+", + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("End time period"), + related_name="+", ) - groups = models.ManyToManyField("core.Group", related_name="events", verbose_name=_("Groups")) - rooms = models.ManyToManyField("Room", related_name="events", verbose_name=_("Rooms")) + groups = models.ManyToManyField( + "core.Group", related_name="events", verbose_name=_("Groups") + ) + rooms = models.ManyToManyField( + "Room", related_name="events", verbose_name=_("Rooms") + ) teachers = models.ManyToManyField( "core.Person", related_name="events", verbose_name=_("Teachers") ) @@ -858,7 +932,9 @@ class Event( class Meta: ordering = ["date_start"] - indexes = [models.Index(fields=["period_from", "period_to", "date_start", "date_end"])] + indexes = [ + models.Index(fields=["period_from", "period_to", "date_start", "date_end"]) + ] verbose_name = _("Event") verbose_name_plural = _("Events") @@ -868,9 +944,14 @@ class ExtraLesson(SchoolTermRelatedExtensibleModel, GroupPropertiesMixin): objects = CurrentSiteManager.from_queryset(ExtraLessonQuerySet)() - week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week) + week = models.IntegerField( + verbose_name=_("Week"), default=CalendarWeek.current_week + ) period = models.ForeignKey( - "TimePeriod", models.CASCADE, related_name="extra_lessons", verbose_name=_("Time period"), + "TimePeriod", + models.CASCADE, + related_name="extra_lessons", + verbose_name=_("Time period"), ) subject = models.ForeignKey( @@ -883,13 +964,21 @@ class ExtraLesson(SchoolTermRelatedExtensibleModel, GroupPropertiesMixin): "core.Group", related_name="extra_lessons", verbose_name=_("Groups") ) teachers = models.ManyToManyField( - "core.Person", related_name="extra_lessons_as_teacher", verbose_name=_("Teachers"), + "core.Person", + related_name="extra_lessons_as_teacher", + verbose_name=_("Teachers"), ) room = models.ForeignKey( - "Room", models.CASCADE, null=True, related_name="extra_lessons", verbose_name=_("Room"), + "Room", + models.CASCADE, + null=True, + related_name="extra_lessons", + verbose_name=_("Room"), ) - comment = models.CharField(verbose_name=_("Comment"), blank=True, null=True, max_length=255) + comment = models.CharField( + verbose_name=_("Comment"), blank=True, null=True, max_length=255 + ) def __str__(self): return f"{self.week}, {self.period}, {self.subject}" diff --git a/aleksis/apps/chronos/preferences.py b/aleksis/apps/chronos/preferences.py index cddfb3f0c8be0fbf9f2aeeafa27fcec971a318c0..4230ceaa88797ebaf32704b695dd2553b8a816e2 100644 --- a/aleksis/apps/chronos/preferences.py +++ b/aleksis/apps/chronos/preferences.py @@ -3,7 +3,10 @@ from django.utils.translation import gettext as _ from dynamic_preferences.preferences import Section from dynamic_preferences.types import BooleanPreference, IntegerPreference -from aleksis.core.registries import person_preferences_registry, site_preferences_registry +from aleksis.core.registries import ( + person_preferences_registry, + site_preferences_registry, +) chronos = Section("chronos", verbose_name=_("Chronos")) @@ -27,7 +30,9 @@ class ShortenGroups(BooleanPreference): name = "shorten_groups" default = True verbose_name = _("Shorten groups in timetable views") - help_text = _("If there are more groups than the set limit, they will be collapsed.") + help_text = _( + "If there are more groups than the set limit, they will be collapsed." + ) @site_preferences_registry.register diff --git a/aleksis/apps/chronos/rules.py b/aleksis/apps/chronos/rules.py index 7ee9d1e0dcfb7b937b24ef82bb1adf36fa10dc46..d780725cb1f6a4e56be12d1db83280a79efd191a 100644 --- a/aleksis/apps/chronos/rules.py +++ b/aleksis/apps/chronos/rules.py @@ -11,7 +11,9 @@ from .models import LessonSubstitution from .util.predicates import has_timetable_perm # View timetable overview -view_timetable_overview_predicate = has_person & has_global_perm("chronos.view_timetable_overview") +view_timetable_overview_predicate = has_person & has_global_perm( + "chronos.view_timetable_overview" +) add_perm("chronos.view_timetable_overview", view_timetable_overview_predicate) # View my timetable diff --git a/aleksis/apps/chronos/tables.py b/aleksis/apps/chronos/tables.py index bc4011f3ef0ebaaad9509ae0d55d9b7a245f675d..92a966fe11a3d866bdd9d160ebba712ab4e3066d 100644 --- a/aleksis/apps/chronos/tables.py +++ b/aleksis/apps/chronos/tables.py @@ -31,8 +31,12 @@ class LessonsTable(tables.Table): row_attrs = {"class": _css_class_from_lesson_state} period__period = tables.Column(accessor="period__period") - lesson__groups = tables.Column(accessor="lesson__group_names", verbose_name=_("Groups")) - lesson__teachers = tables.Column(accessor="lesson__teacher_names", verbose_name=_("Teachers")) + lesson__groups = tables.Column( + accessor="lesson__group_names", verbose_name=_("Groups") + ) + lesson__teachers = tables.Column( + accessor="lesson__teacher_names", verbose_name=_("Teachers") + ) lesson__subject = tables.Column(accessor="lesson__subject") room = tables.Column(accessor="room") edit_substitution = tables.LinkColumn( diff --git a/aleksis/apps/chronos/templatetags/week_helpers.py b/aleksis/apps/chronos/templatetags/week_helpers.py index c97703175ec5c4f39cf1757b5ee426bddb4e0dbb..727afdf7bf99d28363f84cdba08f21233974df18 100644 --- a/aleksis/apps/chronos/templatetags/week_helpers.py +++ b/aleksis/apps/chronos/templatetags/week_helpers.py @@ -4,7 +4,11 @@ from typing import Optional, Union from django import template from django.db.models.query import QuerySet -from aleksis.apps.chronos.util.date import CalendarWeek, week_period_to_date, week_weekday_to_date +from aleksis.apps.chronos.util.date import ( + CalendarWeek, + week_period_to_date, + week_weekday_to_date, +) register = template.Library() diff --git a/aleksis/apps/chronos/urls.py b/aleksis/apps/chronos/urls.py index 666183ec6a43d80b897b05643288a77ee8b615b7..3d68c3a18451570254e2d5323221bd12a31352ba 100644 --- a/aleksis/apps/chronos/urls.py +++ b/aleksis/apps/chronos/urls.py @@ -17,11 +17,15 @@ urlpatterns = [ name="timetable_by_week", ), path( - "timetable/<str:type_>/<int:pk>/<str:regular>/", views.timetable, name="timetable_regular", + "timetable/<str:type_>/<int:pk>/<str:regular>/", + views.timetable, + name="timetable_regular", ), path("lessons/", views.lessons_day, name="lessons_day"), path( - "lessons/<int:year>/<int:month>/<int:day>/", views.lessons_day, name="lessons_day_by_date", + "lessons/<int:year>/<int:month>/<int:day>/", + views.lessons_day, + name="lessons_day_by_date", ), path( "lessons/<int:id_>/<int:week>/substition/", @@ -35,7 +39,10 @@ urlpatterns = [ ), path("substitutions/", views.substitutions, name="substitutions"), path( - "substitutions/print/", views.substitutions, {"is_print": True}, name="substitutions_print", + "substitutions/print/", + views.substitutions, + {"is_print": True}, + name="substitutions_print", ), path( "substitutions/<int:year>/<int:month>/<int:day>/", diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py index 89b32ae3fdb60adedcfe582bfde8d0147677533b..48fc7cddcf4d5e909f49c45525ffc61606e7edde 100644 --- a/aleksis/apps/chronos/util/build.py +++ b/aleksis/apps/chronos/util/build.py @@ -21,7 +21,9 @@ ExtraLesson = apps.get_model("chronos", "ExtraLesson") def build_timetable( - type_: Union[TimetableType, str], obj: Union[int, Person], date_ref: Union[CalendarWeek, date], + type_: Union[TimetableType, str], + obj: Union[int, Person], + date_ref: Union[CalendarWeek, date], ): needed_breaks = [] @@ -48,7 +50,9 @@ def build_timetable( if is_person: lesson_periods = LessonPeriod.objects.daily_lessons_for_person(obj, date_ref) else: - lesson_periods = LessonPeriod.objects.in_week(date_ref).filter_from_type(type_, obj) + lesson_periods = LessonPeriod.objects.in_week(date_ref).filter_from_type( + type_, obj + ) # Sort lesson periods in a dict lesson_periods_per_period = lesson_periods.group_by_periods(is_person=is_person) @@ -57,7 +61,9 @@ def build_timetable( if is_person: extra_lessons = ExtraLesson.objects.on_day(date_ref).filter_from_person(obj) else: - extra_lessons = ExtraLesson.objects.filter(week=date_ref.week).filter_from_type(type_, obj) + extra_lessons = ExtraLesson.objects.filter(week=date_ref.week).filter_from_type( + type_, obj + ) # Sort lesson periods in a dict extra_lessons_per_period = extra_lessons.group_by_periods(is_person=is_person) @@ -143,7 +149,10 @@ def build_timetable( if period_after_break not in needed_breaks: needed_breaks.append(period_after_break) - if not is_person and period_after_break not in supervisions_per_period_after: + if ( + not is_person + and period_after_break not in supervisions_per_period_after + ): supervisions_per_period_after[period_after_break] = {} if is_person: @@ -169,7 +178,9 @@ def build_timetable( if not is_person: cols = [] - for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1): + for weekday in range( + TimePeriod.weekday_min, TimePeriod.weekday_max + 1 + ): col = None if ( period in supervisions_per_period_after @@ -198,21 +209,32 @@ def build_timetable( if not is_person: cols = [] - for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1): + for weekday in range( + TimePeriod.weekday_min, TimePeriod.weekday_max + 1 + ): col = [] # Add lesson periods - if period in lesson_periods_per_period and weekday not in holidays_per_weekday: + if ( + period in lesson_periods_per_period + and weekday not in holidays_per_weekday + ): if weekday in lesson_periods_per_period[period]: col += lesson_periods_per_period[period][weekday] # Add extra lessons - if period in extra_lessons_per_period and weekday not in holidays_per_weekday: + if ( + period in extra_lessons_per_period + and weekday not in holidays_per_weekday + ): if weekday in extra_lessons_per_period[period]: col += extra_lessons_per_period[period][weekday] # Add events - if period in events_per_period and weekday not in holidays_per_weekday: + if ( + period in events_per_period + and weekday not in holidays_per_weekday + ): if weekday in events_per_period[period]: col += events_per_period[period][weekday] @@ -309,7 +331,9 @@ def build_substitutions_list(wanted_day: date) -> List[dict]: return rows -def build_weekdays(base: List[Tuple[int, str]], wanted_week: CalendarWeek) -> List[dict]: +def build_weekdays( + base: List[Tuple[int, str]], wanted_week: CalendarWeek +) -> List[dict]: holidays_per_weekday = Holiday.in_week(wanted_week) weekdays = [] @@ -319,7 +343,9 @@ def build_weekdays(base: List[Tuple[int, str]], wanted_week: CalendarWeek) -> Li "key": key, "name": name, "date": wanted_week[key], - "holiday": holidays_per_weekday[key] if key in holidays_per_weekday else None, + "holiday": holidays_per_weekday[key] + if key in holidays_per_weekday + else None, } weekdays.append(weekday) diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index 96a332d946053fcb6364c717e3c4e4cea07bac7e..398db0e6505228b0d2432307d45fd885cb05fd2c 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -30,16 +30,19 @@ def all_timetables(request: HttpRequest) -> HttpResponse: """View all timetables for persons, groups and rooms.""" context = {} - teachers = Person.objects.annotate(lessons_count=Count("lessons_as_teacher")).filter( - lessons_count__gt=0 - ) + teachers = Person.objects.annotate( + lessons_count=Count("lessons_as_teacher") + ).filter(lessons_count__gt=0) groups = Group.objects.annotate( - lessons_count=Count("lessons"), child_lessons_count=Count("child_groups__lessons"), + lessons_count=Count("lessons"), + child_lessons_count=Count("child_groups__lessons"), ) classes = groups.filter(lessons_count__gt=0, parent_groups=None) | groups.filter( child_lessons_count__gt=0, parent_groups=None ) - rooms = Room.objects.annotate(lessons_count=Count("lesson_periods")).filter(lessons_count__gt=0) + rooms = Room.objects.annotate(lessons_count=Count("lesson_periods")).filter( + lessons_count__gt=0 + ) context["teachers"] = teachers context["classes"] = classes @@ -62,7 +65,9 @@ def my_timetable( wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) if has_person(request.user): person = request.user.person @@ -133,7 +138,9 @@ def timetable( # Build lists with weekdays and corresponding dates (long and short variant) context["weekdays"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES, wanted_week) - context["weekdays_short"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week) + context["weekdays_short"] = build_weekdays( + TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week + ) context["weeks"] = get_weeks_for_year(year=wanted_week.year) context["week"] = wanted_week @@ -180,7 +187,9 @@ def lessons_day( wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) # Get lessons lesson_periods = LessonPeriod.objects.on_day(wanted_day) @@ -234,7 +243,9 @@ def edit_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse messages.success(request, _("The substitution has been saved.")) date = wanted_week[lesson_period.period.weekday] - return redirect("lessons_day_by_date", year=date.year, month=date.month, day=date.day) + return redirect( + "lessons_day_by_date", year=date.year, month=date.month, day=date.day + ) context["edit_substitution_form"] = edit_substitution_form @@ -255,7 +266,9 @@ def delete_substitution(request: HttpRequest, id_: int, week: int) -> HttpRespon messages.success(request, _("The substitution has been deleted.")) date = wanted_week[lesson_period.period.weekday] - return redirect("lessons_day_by_date", year=date.year, month=date.month, day=date.day) + return redirect( + "lessons_day_by_date", year=date.year, month=date.month, day=date.day + ) @permission_required("chronos.view_substitutions") @@ -273,7 +286,9 @@ def substitutions( wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) day_number = get_site_preferences()["chronos__substitutions_print_number_of_days"] day_contexts = {}