diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py
index e381407c49f10943904f11d50f6d56a7d8c31757..f65e2383713b5bf57624ef551dbf5b503b90c154 100644
--- a/aleksis/apps/alsijil/model_extensions.py
+++ b/aleksis/apps/alsijil/model_extensions.py
@@ -3,6 +3,7 @@ from typing import Dict, Optional, Union
 
 from django.db.models import Exists, OuterRef, QuerySet
 
+import reversion
 from calendarweek import CalendarWeek
 
 from aleksis.apps.chronos.models import LessonPeriod
@@ -45,21 +46,26 @@ def mark_absent(
 
     # Create and update all personal notes for the discovered lesson periods
     for lesson_period in lesson_periods:
-        personal_note, created = PersonalNote.objects.update_or_create(
-            person=self,
-            lesson_period=lesson_period,
-            week=wanted_week.week,
-            year=wanted_week.year,
-            defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type},
-        )
-        personal_note.groups_of_person.set(self.member_of.all())
-
-        if remarks:
-            if personal_note.remarks:
-                personal_note.remarks += "; %s" % remarks
-            else:
-                personal_note.remarks = remarks
-            personal_note.save()
+        with reversion.create_revision():
+            personal_note, created = PersonalNote.objects.update_or_create(
+                person=self,
+                lesson_period=lesson_period,
+                week=wanted_week.week,
+                year=wanted_week.year,
+                defaults={
+                    "absent": absent,
+                    "excused": excused,
+                    "excuse_type": excuse_type,
+                },
+            )
+            personal_note.groups_of_person.set(self.member_of.all())
+
+            if remarks:
+                if personal_note.remarks:
+                    personal_note.remarks += "; %s" % remarks
+                else:
+                    personal_note.remarks = remarks
+                personal_note.save()
 
 
 @LessonPeriod.method
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 721648bc4f52ddb4728de84f21319635ee9a014f..ea951fd97a4a7676d775070440a77e8b1b68783e 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -1,4 +1,5 @@
 from django.db import models
+from django.utils.formats import date_format
 from django.utils.translation import gettext_lazy as _
 
 from calendarweek import CalendarWeek
@@ -82,6 +83,25 @@ class PersonalNote(ExtensibleModel, WeekRelatedMixin):
             self.excuse_type = None
         super().save(*args, **kwargs)
 
+    def reset_values(self):
+        """Reset all saved data to default values.
+
+        .. warning ::
+
+            This won't save the data, please execute ``save`` extra.
+        """
+        defaults = PersonalNote()
+
+        self.absent = defaults.absent
+        self.late = defaults.late
+        self.excused = defaults.excused
+        self.excuse_type = defaults.excuse_type
+        self.remarks = defaults.remarks
+        self.extra_marks.clear()
+
+    def __str__(self):
+        return f"{date_format(self.date)}, {self.lesson_period}, {self.person}"
+
     class Meta:
         verbose_name = _("Personal note")
         verbose_name_plural = _("Personal notes")
diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
index 5a442b81c4fbb2956034bb26dc1f7c98ccbab4f8..dd907383585e258879539a07508a5e9c0aae7b81 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
@@ -27,6 +27,10 @@
             {% trans "Mark as" %}
             <input type="hidden" value="{{ note.pk }}" name="personal_note">
             {% include "alsijil/partials/mark_as_buttons.html" %}
+            <a class="btn-flat red-text" title="{% trans "Delete note" %}"
+               href="{% url "delete_personal_note" note.pk %}">
+              <i class="material-icons center">cancel</i>
+            </a>
           </form>
           <i class="material-icons left red-text">warning</i>
           <p class="no-margin">
@@ -40,6 +44,10 @@
             {% trans "Mark as" %}
             <input type="hidden" value="{{ note.pk }}" name="personal_note">
             {% include "alsijil/partials/mark_as_buttons.html" %}
+            <a class="btn-flat red-text" title="{% trans "Delete note" %}"
+               href="{% url "delete_personal_note" note.pk %}">
+              <i class="material-icons center">cancel</i>
+            </a>
           </form>
         </li>
       {% empty %}
@@ -152,6 +160,10 @@
                         {% trans "Mark as" %}
                         <input type="hidden" value="{{ note.pk }}" name="personal_note">
                         {% include "alsijil/partials/mark_as_buttons.html" %}
+                        <a class="btn-flat red-text" title="{% trans "Delete note" %}"
+                           href="{% url "delete_personal_note" note.pk %}">
+                          <i class="material-icons center">cancel</i>
+                        </a>
                       </form>
                     {% endif %}
 
@@ -190,6 +202,10 @@
                         {% trans "Mark as" %}
                         <input type="hidden" value="{{ note.pk }}" name="personal_note">
                         {% include "alsijil/partials/mark_as_buttons.html" %}
+                        <a class="btn-flat red-text" title="{% trans "Delete note" %}"
+                           href="{% url "delete_personal_note" note.pk %}">
+                          <i class="material-icons center">cancel</i>
+                        </a>
                       </form>
                     {% endif %}
                   </div>
diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py
index 0482571bd3cd9cf7c7da4a15b4cd7fc3e0a58c36..e2bba60a0df002ccf4b110ea8ac5f1e22df8387a 100644
--- a/aleksis/apps/alsijil/urls.py
+++ b/aleksis/apps/alsijil/urls.py
@@ -29,6 +29,11 @@ urlpatterns = [
     path("persons/", views.my_students, name="my_students"),
     path("persons/<int:id_>/", views.overview_person, name="overview_person"),
     path("me/", views.overview_person, name="overview_me"),
+    path(
+        "notes/<int:pk>/delete/",
+        views.DeletePersonalNoteView.as_view(),
+        name="delete_personal_note",
+    ),
     path("absence/new", views.register_absence, name="register_absence"),
     path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"),
     path(
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index f9840a124ee64626238b77031039837b96525554..ce85d10136b7a1f566b4c4ad27b8afeb9369d35a 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -7,7 +7,9 @@ from django.http import Http404, HttpRequest, HttpResponse, HttpResponseNotFound
 from django.shortcuts import get_object_or_404, redirect, render
 from django.urls import reverse, reverse_lazy
 from django.utils.translation import ugettext as _
+from django.views.generic import DetailView
 
+import reversion
 from calendarweek import CalendarWeek
 from django_tables2 import SingleTableView
 from reversion.views import RevisionMixin
@@ -125,7 +127,8 @@ def lesson(
             or not get_site_preferences()["alsijil__block_personal_notes_for_cancelled"]
         ):
             if personal_note_formset.is_valid():
-                instances = personal_note_formset.save()
+                with reversion.create_revision():
+                    instances = personal_note_formset.save()
 
                 # Iterate over personal notes and carry changed absences to following lessons
                 for instance in instances:
@@ -508,7 +511,12 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
                             absent=True,
                             excused=False,
                         )
-                        notes.update(excused=True, excuse_type=excuse_type)
+                        for note in notes:
+                            note.excused = True
+                            note.excuse_type = excuse_type
+                            with reversion.create_revision():
+                                note.save()
+
                         messages.success(
                             request, _("The absences have been marked as excused.")
                         )
@@ -523,7 +531,8 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
                         if note.absent:
                             note.excused = True
                             note.excuse_type = excuse_type
-                            note.save()
+                            with reversion.create_revision():
+                                note.save()
                             messages.success(
                                 request, _("The absence has been marked as excused.")
                             )
@@ -638,6 +647,19 @@ def register_absence(request: HttpRequest) -> HttpResponse:
     return render(request, "alsijil/absences/register.html", context)
 
 
+class DeletePersonalNoteView(DetailView):
+    model = PersonalNote
+    template_name = "core/pages/delete.html"
+
+    def post(self, request, *args, **kwargs):
+        note = self.get_object()
+        with reversion.create_revision():
+            note.reset_values()
+            note.save()
+        messages.success(request, _("The personal note has been deleted."))
+        return redirect("overview_person", note.person.pk)
+
+
 class ExtraMarkListView(SingleTableView, PermissionRequiredMixin):
     """Table of all extra marks."""