diff --git a/biscuit/apps/alsijil/__init__.py b/biscuit/apps/alsijil/__init__.py
index 371cf243f88de52487b102ab7586df6babc62b1e..13d0907873673eb2aec31f7847e7f5018954b090 100644
--- a/biscuit/apps/alsijil/__init__.py
+++ b/biscuit/apps/alsijil/__init__.py
@@ -1,8 +1,8 @@
 import pkg_resources
 
 try:
-    __version__ = pkg_resources.get_distribution('BiscuIT-App-Alsijil').version
+    __version__ = pkg_resources.get_distribution("BiscuIT-App-Alsijil").version
 except Exception:
-    __version__ = 'unknown'
+    __version__ = "unknown"
 
-default_app_config = 'biscuit.apps.alsijil.apps.AlsijilConfig'
+default_app_config = "biscuit.apps.alsijil.apps.AlsijilConfig"
diff --git a/biscuit/apps/alsijil/apps.py b/biscuit/apps/alsijil/apps.py
index 23151cb6a2f08900d6c3626b0ab8020a3244d262..8fb3b07a4895eb9cbe7046c437a559c35ee3d182 100644
--- a/biscuit/apps/alsijil/apps.py
+++ b/biscuit/apps/alsijil/apps.py
@@ -2,5 +2,5 @@ from biscuit.core.util.apps import AppConfig
 
 
 class AlsijilConfig(AppConfig):
-    name = 'biscuit.apps.alsijil'
-    verbose_name = 'BiscuIT - Alsijil (Class register)'
+    name = "biscuit.apps.alsijil"
+    verbose_name = "BiscuIT - Alsijil (Class register)"
diff --git a/biscuit/apps/alsijil/forms.py b/biscuit/apps/alsijil/forms.py
index 53bb755241c768293d633840adb5356c8656d9f8..1a0602b312c16feee86015c8a394d9876573826a 100644
--- a/biscuit/apps/alsijil/forms.py
+++ b/biscuit/apps/alsijil/forms.py
@@ -1,8 +1,10 @@
+from datetime import datetime
+
 from django import forms
 from django.db.models import Count
 from django.utils.translation import ugettext_lazy as _
+
 from django_select2.forms import Select2Widget
-from datetime import datetime
 
 from biscuit.apps.chronos.models import Room
 from biscuit.core.models import Group, Person
@@ -13,54 +15,75 @@ from .models import LessonDocumentation, PersonalNote, PersonalNoteFilter
 class LessonDocumentationForm(forms.ModelForm):
     class Meta:
         model = LessonDocumentation
-        fields = ['topic', 'homework']
+        fields = ["topic", "homework"]
 
 
 class PersonalNoteForm(forms.ModelForm):
     class Meta:
         model = PersonalNote
-        fields = ['absent', 'late', 'excused', 'remarks']
+        fields = ["absent", "late", "excused", "remarks"]
 
     person_name = forms.CharField(disabled=True)
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
-        self.fields['person_name'].widget.attrs.update(
-            {'class': 'alsijil-lesson-personal-note-name'})
+        self.fields["person_name"].widget.attrs.update(
+            {"class": "alsijil-lesson-personal-note-name"}
+        )
 
-        if self.instance and getattr(self.instance, 'person', None):
-            self.fields['person_name'].initial = str(self.instance.person)
+        if self.instance and getattr(self.instance, "person", None):
+            self.fields["person_name"].initial = str(self.instance.person)
 
 
 class SelectForm(forms.Form):
     group = forms.ModelChoiceField(
-        queryset=Group.objects.annotate(lessons_count=Count('lessons')).filter(lessons_count__gt=0),
-        label=_('Group'), required=False, widget=Select2Widget)
+        queryset=Group.objects.annotate(lessons_count=Count("lessons")).filter(
+            lessons_count__gt=0
+        ),
+        label=_("Group"),
+        required=False,
+        widget=Select2Widget,
+    )
     teacher = forms.ModelChoiceField(
-        queryset=Person.objects.annotate(lessons_count=Count(
-            'lessons_as_teacher')).filter(lessons_count__gt=0),
-        label=_('Teacher'), required=False, widget=Select2Widget)
+        queryset=Person.objects.annotate(
+            lessons_count=Count("lessons_as_teacher")
+        ).filter(lessons_count__gt=0),
+        label=_("Teacher"),
+        required=False,
+        widget=Select2Widget,
+    )
     room = forms.ModelChoiceField(
-        queryset=Room.objects.annotate(lessons_count=Count(
-            'lesson_periods')).filter(lessons_count__gt=0),
-        label=_('Room'), required=False, widget=Select2Widget)
+        queryset=Room.objects.annotate(lessons_count=Count("lesson_periods")).filter(
+            lessons_count__gt=0
+        ),
+        label=_("Room"),
+        required=False,
+        widget=Select2Widget,
+    )
 
 
 PersonalNoteFormSet = forms.modelformset_factory(
-    PersonalNote, form=PersonalNoteForm, max_num=0, extra=0)
+    PersonalNote, form=PersonalNoteForm, max_num=0, extra=0
+)
 
 
 class RegisterAbsenceForm(forms.Form):
-    date_start = forms.DateField(label=_('Start date'), widget=forms.SelectDateWidget, initial=datetime.today)
-    date_end = forms.DateField(label=_('End date'), widget=forms.SelectDateWidget, initial=datetime.today)
-    from_period = forms.IntegerField(label=_('From period'), initial=0, min_value=0)
-    person = forms.ModelChoiceField(label=_('Person'), queryset=Person.objects.all(), widget=Select2Widget)
-    absent = forms.BooleanField(label=_('Absent'), initial=True, required=False)
-    excused = forms.BooleanField(label=_('Excused'), initial=True, required=False)
-    remarks = forms.CharField(label=_('Remarks'), max_length=30, required=False)
+    date_start = forms.DateField(
+        label=_("Start date"), widget=forms.SelectDateWidget, initial=datetime.today
+    )
+    date_end = forms.DateField(
+        label=_("End date"), widget=forms.SelectDateWidget, initial=datetime.today
+    )
+    from_period = forms.IntegerField(label=_("From period"), initial=0, min_value=0)
+    person = forms.ModelChoiceField(
+        label=_("Person"), queryset=Person.objects.all(), widget=Select2Widget
+    )
+    absent = forms.BooleanField(label=_("Absent"), initial=True, required=False)
+    excused = forms.BooleanField(label=_("Excused"), initial=True, required=False)
+    remarks = forms.CharField(label=_("Remarks"), max_length=30, required=False)
 
 
 class PersonalNoteFilterForm(forms.ModelForm):
     class Meta:
         model = PersonalNoteFilter
-        fields = ['identifier', 'description', 'regex']
+        fields = ["identifier", "description", "regex"]
diff --git a/biscuit/apps/alsijil/menus.py b/biscuit/apps/alsijil/menus.py
index 71a57bda5b2c6e651712250c8755a50887b5bdb9..4e6abca1c2658a3e63a3549e82651be05dfe0cd7 100644
--- a/biscuit/apps/alsijil/menus.py
+++ b/biscuit/apps/alsijil/menus.py
@@ -1,34 +1,37 @@
 from django.utils.translation import ugettext_lazy as _
 
 MENUS = {
-    'NAV_MENU_CORE': [
+    "NAV_MENU_CORE": [
         {
-            'name': _('Class register'),
-            'url': '#',
-            'root': True,
-            'validators': ['menu_generator.validators.is_authenticated', 'biscuit.core.util.core_helpers.has_person'],
-            'submenu': [
+            "name": _("Class register"),
+            "url": "#",
+            "root": True,
+            "validators": [
+                "menu_generator.validators.is_authenticated",
+                "biscuit.core.util.core_helpers.has_person",
+            ],
+            "submenu": [
                 {
-                    'name': _('Current lesson'),
-                    'url': 'lesson',
-                    'validators': ['menu_generator.validators.is_authenticated']
+                    "name": _("Current lesson"),
+                    "url": "lesson",
+                    "validators": ["menu_generator.validators.is_authenticated"],
                 },
                 {
-                    'name': _('Current week'),
-                    'url': 'week_view',
-                    'validators': ['menu_generator.validators.is_authenticated']
+                    "name": _("Current week"),
+                    "url": "week_view",
+                    "validators": ["menu_generator.validators.is_authenticated"],
                 },
                 {
-                    'name': _('Register absence'),
-                    'url': 'register_absence',
-                    'validators': ['menu_generator.validators.is_superuser']
+                    "name": _("Register absence"),
+                    "url": "register_absence",
+                    "validators": ["menu_generator.validators.is_superuser"],
                 },
                 {
-                    'name': _('Personal note filters'),
-                    'url': 'list_personal_note_filters',
-                    'validators': ['menu_generator.validators.is_superuser']
-                }
-            ]
+                    "name": _("Personal note filters"),
+                    "url": "list_personal_note_filters",
+                    "validators": ["menu_generator.validators.is_superuser"],
+                },
+            ],
         }
     ]
 }
diff --git a/biscuit/apps/alsijil/migrations/0001_initial.py b/biscuit/apps/alsijil/migrations/0001_initial.py
index d38957551456538c954cfbc17a691a8378f39882..5de48ef84f0aa2b955059baeadcb1fb7671b87ee 100644
--- a/biscuit/apps/alsijil/migrations/0001_initial.py
+++ b/biscuit/apps/alsijil/migrations/0001_initial.py
@@ -1,8 +1,9 @@
 # Generated by Django 2.2.5 on 2019-09-03 18:30
 
-import biscuit.core.util.core_helpers
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
+
+import biscuit.core.util.core_helpers
 
 
 class Migration(migrations.Migration):
@@ -10,42 +11,114 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('chronos', '0001_initial'),
-        ('core', '0001_initial'),
+        ("chronos", "0001_initial"),
+        ("core", "0001_initial"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='PersonalNote',
+            name="PersonalNote",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('week', models.IntegerField()),
-                ('absent', models.BooleanField(default=False)),
-                ('late', models.IntegerField(default=0)),
-                ('excused', models.BooleanField(default=False)),
-                ('remarks', models.CharField(blank=True, max_length=200)),
-                ('lesson_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='chronos.LessonPeriod')),
-                ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='core.Person')),
-                ('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("week", models.IntegerField()),
+                ("absent", models.BooleanField(default=False)),
+                ("late", models.IntegerField(default=0)),
+                ("excused", models.BooleanField(default=False)),
+                ("remarks", models.CharField(blank=True, max_length=200)),
+                (
+                    "lesson_period",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="chronos.LessonPeriod",
+                    ),
+                ),
+                (
+                    "person",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="personal_notes",
+                        to="core.Person",
+                    ),
+                ),
+                (
+                    "school",
+                    models.ForeignKey(
+                        default=1,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="core.School",
+                    ),
+                ),
             ],
             options={
-                'ordering': ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period', 'person__last_name', 'person__first_name'],
-                'unique_together': {('school', 'lesson_period', 'week', 'person')},
+                "ordering": [
+                    "lesson_period__lesson__date_start",
+                    "week",
+                    "lesson_period__period__weekday",
+                    "lesson_period__period__period",
+                    "person__last_name",
+                    "person__first_name",
+                ],
+                "unique_together": {("school", "lesson_period", "week", "person")},
             },
         ),
         migrations.CreateModel(
-            name='LessonDocumentation',
+            name="LessonDocumentation",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('week', models.IntegerField()),
-                ('topic', models.CharField(blank=True, max_length=200, verbose_name='Lesson topic')),
-                ('homework', models.CharField(blank=True, max_length=200, verbose_name='Homework')),
-                ('lesson_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documentations', to='chronos.LessonPeriod')),
-                ('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("week", models.IntegerField()),
+                (
+                    "topic",
+                    models.CharField(
+                        blank=True, max_length=200, verbose_name="Lesson topic"
+                    ),
+                ),
+                (
+                    "homework",
+                    models.CharField(
+                        blank=True, max_length=200, verbose_name="Homework"
+                    ),
+                ),
+                (
+                    "lesson_period",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="documentations",
+                        to="chronos.LessonPeriod",
+                    ),
+                ),
+                (
+                    "school",
+                    models.ForeignKey(
+                        default=1,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="core.School",
+                    ),
+                ),
             ],
             options={
-                'ordering': ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period'],
-                'unique_together': {('school', 'lesson_period', 'week')},
+                "ordering": [
+                    "lesson_period__lesson__date_start",
+                    "week",
+                    "lesson_period__period__weekday",
+                    "lesson_period__period__period",
+                ],
+                "unique_together": {("school", "lesson_period", "week")},
             },
         ),
     ]
diff --git a/biscuit/apps/alsijil/migrations/0002_add_personal_note_filter.py b/biscuit/apps/alsijil/migrations/0002_add_personal_note_filter.py
index 3f0fd075998a18345723bd09ede35ae3e88971d5..dff35d692073bd6810a42d6649ee219a6762f2eb 100644
--- a/biscuit/apps/alsijil/migrations/0002_add_personal_note_filter.py
+++ b/biscuit/apps/alsijil/migrations/0002_add_personal_note_filter.py
@@ -1,31 +1,66 @@
 # Generated by Django 2.2.5 on 2019-11-20 14:21
 
+import django.db.models.deletion
+from django.db import migrations, models
+
 import biscuit.apps.alsijil.models
 import biscuit.core.util.core_helpers
-from django.db import migrations, models
-import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('core', '0003_school_logo'),
-        ('alsijil', '0001_initial'),
+        ("core", "0003_school_logo"),
+        ("alsijil", "0001_initial"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='PersonalNoteFilter',
+            name="PersonalNoteFilter",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('identifier', models.CharField(max_length=30, validators=[biscuit.apps.alsijil.models.isidentifier], verbose_name='Identifier')),
-                ('description', models.CharField(blank=True, max_length=60, verbose_name='Description')),
-                ('regex', models.CharField(max_length=100, verbose_name='Match expression')),
-                ('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "identifier",
+                    models.CharField(
+                        max_length=30,
+                        validators=[biscuit.apps.alsijil.models.isidentifier],
+                        verbose_name="Identifier",
+                    ),
+                ),
+                (
+                    "description",
+                    models.CharField(
+                        blank=True, max_length=60, verbose_name="Description"
+                    ),
+                ),
+                (
+                    "regex",
+                    models.CharField(max_length=100, verbose_name="Match expression"),
+                ),
+                (
+                    "school",
+                    models.ForeignKey(
+                        default=1,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="core.School",
+                    ),
+                ),
             ],
             options={
-                'ordering': ['identifier'],
-                'unique_together': {('school', 'regex'), ('school', 'description'), ('school', 'identifier')},
+                "ordering": ["identifier"],
+                "unique_together": {
+                    ("school", "regex"),
+                    ("school", "description"),
+                    ("school", "identifier"),
+                },
             },
         ),
     ]
diff --git a/biscuit/apps/alsijil/model_extensions.py b/biscuit/apps/alsijil/model_extensions.py
index 8cbca4e2f24ecb638525fbbd7ba75cd496dbd181..521e5795e7250c0a44cef5a19f51d9f063582a86 100644
--- a/biscuit/apps/alsijil/model_extensions.py
+++ b/biscuit/apps/alsijil/model_extensions.py
@@ -10,7 +10,14 @@ from .models import PersonalNote
 
 
 @Person.method
-def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excused: bool = False, remarks: str = ''):
+def mark_absent(
+    self,
+    day: date,
+    from_period: int = 0,
+    absent: bool = True,
+    excused: bool = False,
+    remarks: str = "",
+):
     """ Mark a person absent for all lessons in a day, optionally starting with
     a selected period number.
     
@@ -27,9 +34,7 @@ def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excu
     wanted_week = CalendarWeek.from_date(day)
 
     # Get all lessons of this person on the specified day
-    lesson_periods = self.lesson_periods_as_participant.on_day(
-        day
-    ).filter(
+    lesson_periods = self.lesson_periods_as_participant.on_day(day).filter(
         period__period__gte=from_period
     )
 
@@ -39,15 +44,12 @@ def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excu
             person=self,
             lesson_period=lesson_period,
             week=wanted_week.week,
-            defaults={
-                'absent': absent,
-                'excused': excused
-            }
+            defaults={"absent": absent, "excused": excused},
         )
 
         if remarks:
             if personal_note.remarks:
-                personal_note.remarks += '; %s' % remarks
+                personal_note.remarks += "; %s" % remarks
             else:
                 personal_note.remarks = remarks
             personal_note.save()
@@ -69,22 +71,25 @@ def get_personal_notes(self, wanted_week: CalendarWeek):
 
     # Find all persons in the associated groups that do not yet have a personal note for this lesson
     missing_persons = Person.objects.annotate(
-        no_personal_notes=~Exists(PersonalNote.objects.filter(
-            week=wanted_week.week,
-            lesson_period=self,
-            person__pk=OuterRef('pk')
-        ))
+        no_personal_notes=~Exists(
+            PersonalNote.objects.filter(
+                week=wanted_week.week, lesson_period=self, person__pk=OuterRef("pk")
+            )
+        )
     ).filter(
         member_of__in=Group.objects.filter(pk__in=self.lesson.groups.all()),
         is_active=True,
-        no_personal_notes=True
+        no_personal_notes=True,
     )
 
     # Create all missing personal notes
-    PersonalNote.objects.bulk_create([
-        PersonalNote(person=person, lesson_period=self,
-                     week=wanted_week.week) for person in missing_persons
-    ])
+    PersonalNote.objects.bulk_create(
+        [
+            PersonalNote(person=person, lesson_period=self, week=wanted_week.week)
+            for person in missing_persons
+        ]
+    )
 
-    return PersonalNote.objects.select_related('person').filter(
-        lesson_period=self, week=wanted_week.week)
+    return PersonalNote.objects.select_related("person").filter(
+        lesson_period=self, week=wanted_week.week
+    )
diff --git a/biscuit/apps/alsijil/models.py b/biscuit/apps/alsijil/models.py
index 7c7578f449a5a6036a0b8c3982a6c937c0c5f63f..304fdb772ef8b5f6e56558b7fbd77ec3925b7c99 100644
--- a/biscuit/apps/alsijil/models.py
+++ b/biscuit/apps/alsijil/models.py
@@ -13,10 +13,14 @@ class PersonalNote(models.Model):
     absences, excuses and remarks about a student in a single lesson period.
     """
 
-    person = models.ForeignKey('core.Person', models.CASCADE, related_name='personal_notes')
+    person = models.ForeignKey(
+        "core.Person", models.CASCADE, related_name="personal_notes"
+    )
 
     week = models.IntegerField()
-    lesson_period = models.ForeignKey('chronos.LessonPeriod', models.CASCADE, related_name='personal_notes')
+    lesson_period = models.ForeignKey(
+        "chronos.LessonPeriod", models.CASCADE, related_name="personal_notes"
+    )
 
     absent = models.BooleanField(default=False)
     late = models.IntegerField(default=0)
@@ -25,9 +29,15 @@ class PersonalNote(models.Model):
     remarks = models.CharField(max_length=200, blank=True)
 
     class Meta:
-        unique_together = [['lesson_period', 'week', 'person']]
-        ordering = ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday',
-                    'lesson_period__period__period', 'person__last_name', 'person__first_name']
+        unique_together = [["lesson_period", "week", "person"]]
+        ordering = [
+            "lesson_period__lesson__date_start",
+            "week",
+            "lesson_period__period__weekday",
+            "lesson_period__period__period",
+            "person__last_name",
+            "person__first_name",
+        ]
 
 
 class LessonDocumentation(CRUDMixin):
@@ -37,27 +47,38 @@ class LessonDocumentation(CRUDMixin):
 
     week = models.IntegerField()
     lesson_period = models.ForeignKey(
-        'chronos.LessonPeriod', models.CASCADE, related_name='documentations')
+        "chronos.LessonPeriod", models.CASCADE, related_name="documentations"
+    )
 
-    topic = models.CharField(verbose_name=_('Lesson topic'), max_length=200, blank=True)
-    homework = models.CharField(verbose_name=_('Homework'), max_length=200, blank=True)
+    topic = models.CharField(verbose_name=_("Lesson topic"), max_length=200, blank=True)
+    homework = models.CharField(verbose_name=_("Homework"), max_length=200, blank=True)
 
     class Meta:
-        unique_together = [['lesson_period', 'week']]
-        ordering = ['lesson_period__lesson__date_start', 'week',
-                    'lesson_period__period__weekday', 'lesson_period__period__period']
+        unique_together = [["lesson_period", "week"]]
+        ordering = [
+            "lesson_period__lesson__date_start",
+            "week",
+            "lesson_period__period__weekday",
+            "lesson_period__period__period",
+        ]
 
 
 class PersonalNoteFilter(models.Model):
     """ A filter definition that can generate statistics on personal note texts. """
 
-    identifier = models.CharField(verbose_name=_('Identifier'), max_length=30,
-                                  validators=[isidentifier], unique=True)
-    description = models.CharField(verbose_name=_('Description'), max_length=60,
-                                   blank=True, unique=True)
+    identifier = models.CharField(
+        verbose_name=_("Identifier"),
+        max_length=30,
+        validators=[isidentifier],
+        unique=True,
+    )
+    description = models.CharField(
+        verbose_name=_("Description"), max_length=60, blank=True, unique=True
+    )
 
-    regex = models.CharField(verbose_name=_('Match expression'), max_length=100,
-                             unique=True)
+    regex = models.CharField(
+        verbose_name=_("Match expression"), max_length=100, unique=True
+    )
 
     class Meta:
-        ordering = ['identifier']
+        ordering = ["identifier"]
diff --git a/biscuit/apps/alsijil/tables.py b/biscuit/apps/alsijil/tables.py
index 83737766d548541a91bcb96f320c9740b6d9ea60..38c7402f68f310f516b9d503a51da34ab6496601 100644
--- a/biscuit/apps/alsijil/tables.py
+++ b/biscuit/apps/alsijil/tables.py
@@ -1,14 +1,18 @@
 from django.utils.translation import ugettext_lazy as _
+
 import django_tables2 as tables
 from django_tables2.utils import A
 
 
 class PersonalNoteFilterTable(tables.Table):
     class Meta:
-        attrs = {'class': 'table table-striped table-bordered table-hover table-responsive-xl'}
+        attrs = {
+            "class": "table table-striped table-bordered table-hover table-responsive-xl"
+        }
 
     identifier = tables.Column()
     description = tables.Column()
     regex = tables.Column()
     edit_filter = tables.LinkColumn(
-        'edit_personal_note_filter', args=[A('id')], text=_('Edit'))
+        "edit_personal_note_filter", args=[A("id")], text=_("Edit")
+    )
diff --git a/biscuit/apps/alsijil/urls.py b/biscuit/apps/alsijil/urls.py
index 20327ec13f758353bcc9c7e8ecd3a2f78f39ab8a..85c9c25d4e9a4ffc450ea9e683b14ae0aeee1fe5 100644
--- a/biscuit/apps/alsijil/urls.py
+++ b/biscuit/apps/alsijil/urls.py
@@ -2,24 +2,37 @@ from django.urls import path
 
 from . import views
 
-
 urlpatterns = [
-    path('lesson', views.lesson, name='lesson'),
-    path('lesson/<int:year>/<int:week>/<int:period_id>', views.lesson,
-         name='lesson_by_week_and_period'),
-    path('week', views.week_view, name='week_view'),
-    path('week/<int:year>/<int:week>', views.week_view,
-         name='week_view_by_week'),
-    path('print/group/<int:id_>', views.full_register_group,
-         name='full_register_group'),
-    path('absence/new', views.register_absence,
-         name='register_absence'),
-    path('filters/list', views.list_personal_note_filters,
-         name='list_personal_note_filters'),
-    path('filters/create', views.edit_personal_note_filter,
-         name='create_personal_note_filter'),
-    path('filters/edit/<int:id>', views.edit_personal_note_filter,
-         name='edit_personal_note_filter'),
-    path('filters/delete/<int:id_>', views.delete_personal_note_filter,
-         name='delete_personal_note_filter')
+    path("lesson", views.lesson, name="lesson"),
+    path(
+        "lesson/<int:year>/<int:week>/<int:period_id>",
+        views.lesson,
+        name="lesson_by_week_and_period",
+    ),
+    path("week", views.week_view, name="week_view"),
+    path("week/<int:year>/<int:week>", views.week_view, name="week_view_by_week"),
+    path(
+        "print/group/<int:id_>", views.full_register_group, name="full_register_group"
+    ),
+    path("absence/new", views.register_absence, name="register_absence"),
+    path(
+        "filters/list",
+        views.list_personal_note_filters,
+        name="list_personal_note_filters",
+    ),
+    path(
+        "filters/create",
+        views.edit_personal_note_filter,
+        name="create_personal_note_filter",
+    ),
+    path(
+        "filters/edit/<int:id>",
+        views.edit_personal_note_filter,
+        name="edit_personal_note_filter",
+    ),
+    path(
+        "filters/delete/<int:id_>",
+        views.delete_personal_note_filter,
+        name="delete_personal_note_filter",
+    ),
 ]
diff --git a/biscuit/apps/alsijil/views.py b/biscuit/apps/alsijil/views.py
index 1efd9f36d18760e0c737d6a444d8e142fda15bfb..837205238c1f87d4fe605012fe7bd4a8617af0f5 100644
--- a/biscuit/apps/alsijil/views.py
+++ b/biscuit/apps/alsijil/views.py
@@ -13,17 +13,28 @@ from django_tables2 import RequestConfig
 
 from biscuit.apps.chronos.models import LessonPeriod
 from biscuit.apps.chronos.util import CalendarWeek
-from biscuit.core.models import Group, Person, School
 from biscuit.core.decorators import admin_required
+from biscuit.core.models import Group, Person, School
 from biscuit.core.util import messages
 
-from .forms import LessonDocumentationForm, PersonalNoteFormSet, RegisterAbsenceForm, SelectForm, PersonalNoteFilterForm
+from .forms import (
+    LessonDocumentationForm,
+    PersonalNoteFilterForm,
+    PersonalNoteFormSet,
+    RegisterAbsenceForm,
+    SelectForm,
+)
 from .models import LessonDocumentation, PersonalNoteFilter
 from .tables import PersonalNoteFilterTable
 
 
 @login_required
-def lesson(request: HttpRequest, year: Optional[int] = None, week: Optional[int] = None, period_id: Optional[int] = None) -> HttpResponse:
+def lesson(
+    request: HttpRequest,
+    year: Optional[int] = None,
+    week: Optional[int] = None,
+    period_id: Optional[int] = None,
+) -> HttpResponse:
     context = {}
 
     if year and week and period_id:
@@ -32,34 +43,60 @@ def lesson(request: HttpRequest, year: Optional[int] = None, week: Optional[int]
         wanted_week = CalendarWeek(year=year, week=week)
     else:
         # Determine current lesson by current date and time
-        lesson_period = LessonPeriod.objects.at_time().filter_teacher(request.user.person).first()
+        lesson_period = (
+            LessonPeriod.objects.at_time().filter_teacher(request.user.person).first()
+        )
         wanted_week = CalendarWeek()
 
         if lesson_period:
-            return redirect('lesson_by_week_and_period', wanted_week.year, wanted_week.week, lesson_period.pk)
+            return redirect(
+                "lesson_by_week_and_period",
+                wanted_week.year,
+                wanted_week.week,
+                lesson_period.pk,
+            )
         else:
-            raise Http404(_('You either selected an invalid lesson or there is currently no lesson in progress.'))
+            raise Http404(
+                _(
+                    "You either selected an invalid lesson or there is currently no lesson in progress."
+                )
+            )
 
-    if datetime.combine(wanted_week[lesson_period.period.weekday - 1], lesson_period.period.time_start) > datetime.now() and not request.user.is_superuser:
-        raise PermissionDenied(_('You are not allowed to create a lesson documentation for a lesson in the future.'))
+    if (
+        datetime.combine(
+            wanted_week[lesson_period.period.weekday - 1],
+            lesson_period.period.time_start,
+        )
+        > datetime.now()
+        and not request.user.is_superuser
+    ):
+        raise PermissionDenied(
+            _(
+                "You are not allowed to create a lesson documentation for a lesson in the future."
+            )
+        )
 
-    context['lesson_period'] = lesson_period
-    context['week'] = wanted_week
-    context['day'] = wanted_week[lesson_period.period.weekday - 1]
+    context["lesson_period"] = lesson_period
+    context["week"] = wanted_week
+    context["day"] = wanted_week[lesson_period.period.weekday - 1]
 
     # Create or get lesson documentation object; can be empty when first opening lesson
     lesson_documentation, created = LessonDocumentation.objects.get_or_create(
-        lesson_period=lesson_period, week=wanted_week.week)
+        lesson_period=lesson_period, week=wanted_week.week
+    )
     lesson_documentation_form = LessonDocumentationForm(
-        request.POST or None, instance=lesson_documentation, prefix='leson_documentation')
-
+        request.POST or None,
+        instance=lesson_documentation,
+        prefix="leson_documentation",
+    )
 
     # Create a formset that holds all personal notes for all persons in this lesson
     persons_qs = lesson_period.get_personal_notes(wanted_week)
     personal_note_formset = PersonalNoteFormSet(
-        request.POST or None, queryset=persons_qs, prefix='personal_notes')
+        request.POST or None, queryset=persons_qs, prefix="personal_notes"
+    )
 
-    if request.method == 'POST':
+    if request.method == "POST":
         if lesson_documentation_form.is_valid():
             lesson_documentation_form.save()
 
@@ -69,21 +106,23 @@ def lesson(request: HttpRequest, year: Optional[int] = None, week: Optional[int]
             # Iterate over personal notes and carry changed absences to following lessons
             for instance in instances:
                 instance.person.mark_absent(
-                    wanted_week[lesson_period.period.weekday-1],
-                    lesson_period.period.period+1,
+                    wanted_week[lesson_period.period.weekday - 1],
+                    lesson_period.period.period + 1,
                     instance.absent,
-                    instance.excused
+                    instance.excused,
                 )
 
-    context['lesson_documentation'] = lesson_documentation
-    context['lesson_documentation_form'] = lesson_documentation_form
-    context['personal_note_formset'] = personal_note_formset
+    context["lesson_documentation"] = lesson_documentation
+    context["lesson_documentation_form"] = lesson_documentation_form
+    context["personal_note_formset"] = personal_note_formset
 
-    return render(request, 'alsijil/lesson.html', context)
+    return render(request, "alsijil/lesson.html", context)
 
 
 @login_required
-def week_view(request: HttpRequest, year: Optional[int] = None, week: Optional[int] = None) -> HttpResponse:
+def week_view(
+    request: HttpRequest, year: Optional[int] = None, week: Optional[int] = None
+) -> HttpResponse:
     context = {}
 
     if year and week:
@@ -92,21 +131,25 @@ def week_view(request: HttpRequest, year: Optional[int] = None, week: Optional[i
         wanted_week = CalendarWeek()
 
     lesson_periods = LessonPeriod.objects.annotate(
-        has_documentation=Exists(LessonDocumentation.objects.filter(
-            ~Q(topic__exact=''),
-            lesson_period=OuterRef('pk'),
-            week=wanted_week.week
-        ))
+        has_documentation=Exists(
+            LessonDocumentation.objects.filter(
+                ~Q(topic__exact=""), lesson_period=OuterRef("pk"), week=wanted_week.week
+            )
+        )
     ).in_week(wanted_week)
 
     group = None  # FIXME workaround for #38
-    if request.GET.get('group', None) or request.GET.get('teacher', None) or request.GET.get('room', None):
+    if (
+        request.GET.get("group", None)
+        or request.GET.get("teacher", None)
+        or request.GET.get("room", None)
+    ):
         lesson_periods = lesson_periods.filter_from_query(request.GET)
-        if 'group' in request.GET and request.GET['group']:
-            group = Group.objects.get(pk=request.GET['group'])
+        if "group" in request.GET and request.GET["group"]:
+            group = Group.objects.get(pk=request.GET["group"])
         else:
             group = None
-    elif hasattr(request, 'user') and hasattr(request.user, 'person'):
+    elif hasattr(request, "user") and hasattr(request.user, "person"):
         group = request.user.person.owner_of.first()
         if group:
             lesson_periods = lesson_periods.filter_group(group)
@@ -119,28 +162,37 @@ def week_view(request: HttpRequest, year: Optional[int] = None, week: Optional[i
 
     if lesson_periods:
         # Aggregate all personal notes for this group and week
-        persons = Person.objects.filter(
-            is_active=True
-        ).filter(
-            member_of__lessons__lesson_periods__in=lesson_periods
-        ).distinct().prefetch_related(
-            'personal_notes'
-        ).annotate(
-            absences=Count('personal_notes__absent', filter=Q(
-                personal_notes__lesson_period__in=lesson_periods,
-                personal_notes__week=wanted_week.week,
-                personal_notes__absent=True
-            )),
-            unexcused=Count('personal_notes__absent', filter=Q(
-                personal_notes__lesson_period__in=lesson_periods,
-                personal_notes__week=wanted_week.week,
-                personal_notes__absent=True,
-                personal_notes__excused=False
-            )),
-            tardiness=Sum('personal_notes__late', filter=Q(
-                personal_notes__lesson_period__in=lesson_periods,
-                personal_notes__week=wanted_week.week
-            ))
+        persons = (
+            Person.objects.filter(is_active=True)
+            .filter(member_of__lessons__lesson_periods__in=lesson_periods)
+            .distinct()
+            .prefetch_related("personal_notes")
+            .annotate(
+                absences=Count(
+                    "personal_notes__absent",
+                    filter=Q(
+                        personal_notes__lesson_period__in=lesson_periods,
+                        personal_notes__week=wanted_week.week,
+                        personal_notes__absent=True,
+                    ),
+                ),
+                unexcused=Count(
+                    "personal_notes__absent",
+                    filter=Q(
+                        personal_notes__lesson_period__in=lesson_periods,
+                        personal_notes__week=wanted_week.week,
+                        personal_notes__absent=True,
+                        personal_notes__excused=False,
+                    ),
+                ),
+                tardiness=Sum(
+                    "personal_notes__late",
+                    filter=Q(
+                        personal_notes__lesson_period__in=lesson_periods,
+                        personal_notes__week=wanted_week.week,
+                    ),
+                ),
+            )
         )
     else:
         persons = None
@@ -148,19 +200,25 @@ def week_view(request: HttpRequest, year: Optional[int] = None, week: Optional[i
     # Add a form to filter the view
     select_form = SelectForm(request.GET or None)
 
-    context['current_head'] = str(wanted_week)
-    context['week'] = wanted_week
-    context['lesson_periods'] = lesson_periods
-    context['persons'] = persons
-    context['group'] = group
-    context['select_form'] = select_form
+    context["current_head"] = str(wanted_week)
+    context["week"] = wanted_week
+    context["lesson_periods"] = lesson_periods
+    context["persons"] = persons
+    context["group"] = group
+    context["select_form"] = select_form
 
     week_prev = wanted_week - 1
     week_next = wanted_week + 1
-    context['url_prev'] = '%s?%s' % (reverse('week_view_by_week', args=[week_prev.year, week_prev.week]), request.GET.urlencode())
-    context['url_next'] = '%s?%s' % (reverse('week_view_by_week', args=[week_next.year, week_next.week]), request.GET.urlencode())
+    context["url_prev"] = "%s?%s" % (
+        reverse("week_view_by_week", args=[week_prev.year, week_prev.week]),
+        request.GET.urlencode(),
+    )
+    context["url_next"] = "%s?%s" % (
+        reverse("week_view_by_week", args=[week_next.year, week_next.week]),
+        request.GET.urlencode(),
+    )
 
-    return render(request, 'alsijil/week_view.html', context)
+    return render(request, "alsijil/week_view.html", context)
 
 
 @login_required
@@ -170,55 +228,76 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
     group = get_object_or_404(Group, pk=id_)
 
     # Get all lesson periods for the selected group
-    lesson_periods = LessonPeriod.objects.filter_group(
-        group
-    ).distinct().prefetch_related(
-        'documentations', 'personal_notes'
+    lesson_periods = (
+        LessonPeriod.objects.filter_group(group)
+        .distinct()
+        .prefetch_related("documentations", "personal_notes")
     )
 
-    weeks = CalendarWeek.weeks_within(School.objects.first().current_term.date_start, School.objects.first().current_term.date_end)
+    weeks = CalendarWeek.weeks_within(
+        School.objects.first().current_term.date_start,
+        School.objects.first().current_term.date_end,
+    )
     periods_by_day = {}
     for lesson_period in lesson_periods:
         for week in weeks:
             day = week[lesson_period.period.weekday - 1]
 
-            if lesson_period.lesson.date_start <= day and lesson_period.lesson.date_end >= day:
-                documentations = list(filter(lambda d: d.week == week.week, lesson_period.documentations.all()))
-                notes = list(filter(lambda d: d.week == week.week, lesson_period.personal_notes.all()))
+            if (
+                lesson_period.lesson.date_start <= day
+                and lesson_period.lesson.date_end >= day
+            ):
+                documentations = list(
+                    filter(
+                        lambda d: d.week == week.week,
+                        lesson_period.documentations.all(),
+                    )
+                )
+                notes = list(
+                    filter(
+                        lambda d: d.week == week.week,
+                        lesson_period.personal_notes.all(),
+                    )
+                )
                 substitution = lesson_period.get_substitution(week.week)
 
-                periods_by_day.setdefault(day, []).append((lesson_period, documentations, notes, substitution))
+                periods_by_day.setdefault(day, []).append(
+                    (lesson_period, documentations, notes, substitution)
+                )
 
     persons = group.members.annotate(
-        absences=Count('personal_notes__absent', filter=Q(
-            personal_notes__absent=True
-        )),
-        unexcused=Count('personal_notes__absent', filter=Q(
-            personal_notes__absent=True,
-            personal_notes__excused=False
-        )),
-        tardiness=Sum('personal_notes__late')
+        absences=Count("personal_notes__absent", filter=Q(personal_notes__absent=True)),
+        unexcused=Count(
+            "personal_notes__absent",
+            filter=Q(personal_notes__absent=True, personal_notes__excused=False),
+        ),
+        tardiness=Sum("personal_notes__late"),
     )
 
     # FIXME Move to manager
     personal_note_filters = PersonalNoteFilter.objects.all()
     for personal_note_filter in personal_note_filters:
         persons = persons.annotate(
-            **{'_personal_notes_with_%s' % personal_note_filter.identifier: Count(
-                'personal_notes__remarks',
-                filter=Q(personal_notes__remarks__iregex=personal_note_filter.regex)
-            )}
+            **{
+                "_personal_notes_with_%s"
+                % personal_note_filter.identifier: Count(
+                    "personal_notes__remarks",
+                    filter=Q(
+                        personal_notes__remarks__iregex=personal_note_filter.regex
+                    ),
+                )
+            }
         )
 
-    context['persons'] = persons
-    context['personal_note_filters'] = personal_note_filters
-    context['group'] = group
-    context['weeks'] = weeks
-    context['periods_by_day'] = periods_by_day
-    context['today'] = date.today()
-    context['school'] = School.objects.first()
+    context["persons"] = persons
+    context["personal_note_filters"] = personal_note_filters
+    context["group"] = group
+    context["weeks"] = weeks
+    context["periods_by_day"] = periods_by_day
+    context["today"] = date.today()
+    context["school"] = School.objects.first()
 
-    return render(request, 'alsijil/print/full_register.html', context)
+    return render(request, "alsijil/print/full_register.html", context)
 
 
 @admin_required
@@ -227,30 +306,30 @@ def register_absence(request: HttpRequest) -> HttpResponse:
 
     register_absence_form = RegisterAbsenceForm(request.POST or None)
 
-    if request.method == 'POST':
+    if request.method == "POST":
         if register_absence_form.is_valid():
             # Get data from form
-            person = register_absence_form.cleaned_data['person']
-            start_date = register_absence_form.cleaned_data['date_start']
-            end_date = register_absence_form.cleaned_data['date_end']
-            from_period = register_absence_form.cleaned_data['from_period']
-            absent = register_absence_form.cleaned_data['absent']
-            excused = register_absence_form.cleaned_data['excused']
-            remarks = register_absence_form.cleaned_data['remarks']
+            person = register_absence_form.cleaned_data["person"]
+            start_date = register_absence_form.cleaned_data["date_start"]
+            end_date = register_absence_form.cleaned_data["date_end"]
+            from_period = register_absence_form.cleaned_data["from_period"]
+            absent = register_absence_form.cleaned_data["absent"]
+            excused = register_absence_form.cleaned_data["excused"]
+            remarks = register_absence_form.cleaned_data["remarks"]
 
             # Mark person as absent
             delta = end_date - start_date
-            for i in range(delta.days+1):
+            for i in range(delta.days + 1):
                 from_period = from_period if i == 0 else 0
                 day = start_date + timedelta(days=i)
                 person.mark_absent(day, from_period, absent, excused, remarks)
 
-            messages.success(request, _('The absence has been saved.'))
-            return redirect('index')
+            messages.success(request, _("The absence has been saved."))
+            return redirect("index")
 
-    context['register_absence_form'] = register_absence_form
+    context["register_absence_form"] = register_absence_form
 
-    return render(request, 'alsijil/register_absence.html', context)
+    return render(request, "alsijil/register_absence.html", context)
 
 
 def list_personal_note_filters(request: HttpRequest) -> HttpResponse:
@@ -262,33 +341,36 @@ def list_personal_note_filters(request: HttpRequest) -> HttpResponse:
     personal_note_filters_table = PersonalNoteFilterTable(personal_note_filters)
     RequestConfig(request).configure(personal_note_filters_table)
 
-    context['personal_note_filters_table'] = personal_note_filters_table
+    context["personal_note_filters_table"] = personal_note_filters_table
 
-    return render(request, 'alsijil/personal_note_filters.html', context)
+    return render(request, "alsijil/personal_note_filters.html", context)
 
 
-def edit_personal_note_filter(request: HttpRequest, id: Optional['int'] = None) -> HttpResponse:
+def edit_personal_note_filter(
+    request: HttpRequest, id: Optional["int"] = None
+) -> HttpResponse:
     context = {}
 
     if id:
         personal_note_filter = PersonalNoteFilter.objects.get(id=id)
-        context['personal_note_filter'] = personal_note_filter
+        context["personal_note_filter"] = personal_note_filter
         personal_note_filter_form = PersonalNoteFilterForm(
-            request.POST or None, instance=personal_note_filter)
+            request.POST or None, instance=personal_note_filter
+        )
     else:
-        personal_note_filter_form = PersonalNoteFilterForm(
-            request.POST or None)
-    
-    if request.method == 'POST':
+        personal_note_filter_form = PersonalNoteFilterForm(request.POST or None)
+
+    if request.method == "POST":
         if personal_note_filter_form.is_valid():
             personal_note_filter_form.save(commit=True)
 
-            messages.success(request, _('The filter has been saved'))
-            return redirect('list_personal_note_filters')
+            messages.success(request, _("The filter has been saved"))
+            return redirect("list_personal_note_filters")
 
-    context['personal_note_filter_form'] = personal_note_filter_form
+    context["personal_note_filter_form"] = personal_note_filter_form
+
+    return render(request, "alsijil/manage_personal_note_filter.html", context)
 
-    return render(request, 'alsijil/manage_personal_note_filter.html', context)
 
 @admin_required
 def delete_personal_note_filter(request: HttpRequest, id_: int) -> HttpResponse:
@@ -297,8 +379,8 @@ def delete_personal_note_filter(request: HttpRequest, id_: int) -> HttpResponse:
     personal_note_filter = get_object_or_404(PersonalNoteFilter, pk=id_)
 
     PersonalNoteFilter.objects.filter(pk=id_).delete()
-    
-    messages.success(request, _('The filter has been deleted.'))
 
-    context['personal_note_filter'] = personal_note_filter
-    return redirect('list_personal_note_filters')
+    messages.success(request, _("The filter has been deleted."))
+
+    context["personal_note_filter"] = personal_note_filter
+    return redirect("list_personal_note_filters")