diff --git a/aleksis/core/managers.py b/aleksis/core/managers.py
index c0b033cd7c0cd2d405f279c940a38d201017dc07..66cac5f59cb9a328aa36be23f36f5dc481b8e1f1 100644
--- a/aleksis/core/managers.py
+++ b/aleksis/core/managers.py
@@ -8,7 +8,7 @@ from django.db.models.manager import Manager
 
 from calendarweek import CalendarWeek
 from django_cte import CTEManager, CTEQuerySet
-from polymorphic.managers import PolymorphicManager
+from polymorphic.managers import PolymorphicManager, PolymorphicQuerySet
 
 
 class CurrentSiteManagerWithoutMigrations(_CurrentSiteManager):
@@ -123,11 +123,11 @@ class InstalledWidgetsDashboardWidgetOrderManager(Manager):
         return super().get_queryset().filter(widget_id__in=dashboard_widget_pks)
 
 
-class PolymorphicCurrentSiteManager(_CurrentSiteManager, PolymorphicManager):
+class PolymorphicCurrentSiteManager(CurrentSiteManagerWithoutMigrations, PolymorphicManager):
     """Default manager for extensible, polymorphic models."""
 
 
-class HolidayQuerySet(QuerySet, DateRangeQuerySetMixin):
+class HolidayQuerySet(DateRangeQuerySetMixin, PolymorphicQuerySet):
     """QuerySet with custom query methods for holidays."""
 
     def get_all_days(self) -> list[date]:
diff --git a/aleksis/core/migrations/0051_holiday.py b/aleksis/core/migrations/0051_holiday.py
deleted file mode 100644
index 32e4d2081a414047f774ed14efb51b10d3f05e16..0000000000000000000000000000000000000000
--- a/aleksis/core/migrations/0051_holiday.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Generated by Django 4.1.7 on 2023-02-27 14:32
-
-import aleksis.core.mixins
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("sites", "0002_alter_domain_unique"),
-        ("core", "0050_fix_amends"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="Holiday",
-            fields=[
-                (
-                    "id",
-                    models.BigAutoField(
-                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
-                    ),
-                ),
-                ("extended_data", models.JSONField(default=dict, editable=False)),
-                ("holiday_name", models.CharField(max_length=255, verbose_name="Name")),
-                ("date_start", models.DateField(verbose_name="Start date")),
-                ("date_end", models.DateField(verbose_name="End date")),
-                (
-                    "site",
-                    models.ForeignKey(
-                        default=1,
-                        editable=False,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="+",
-                        to="sites.site",
-                    ),
-                ),
-            ],
-            options={
-                "verbose_name": "Holiday",
-                "verbose_name_plural": "Holidays",
-                "ordering": ["date_start"],
-            },
-            bases=(aleksis.core.mixins.CalendarEventMixin, models.Model),
-        ),
-    ]
diff --git a/aleksis/core/migrations/0052_holiday.py b/aleksis/core/migrations/0052_holiday.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed2e75ba011261884c26e9e695f85595d0b63e91
--- /dev/null
+++ b/aleksis/core/migrations/0052_holiday.py
@@ -0,0 +1,36 @@
+# Generated by Django 4.1.8 on 2023-04-09 14:09
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("sites", "0002_alter_domain_unique"),
+        ("core", "0051_calendarevent_dates"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Holiday",
+            fields=[
+                (
+                    "calendarevent_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="core.calendarevent",
+                    ),
+                ),
+                ("holiday_name", models.CharField(max_length=255, verbose_name="Name")),
+            ],
+            options={
+                "verbose_name": "Holiday",
+                "verbose_name_plural": "Holidays",
+            },
+            bases=("core.calendarevent",),
+        ),
+    ]
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index c0086041aa4be99c2a5dbb36ceea72ef569d9723..cf75c7e105713bfdbb3816a3ff9b2596fdc3524e 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -70,6 +70,7 @@ from .managers import (
     GroupQuerySet,
     HolidayQuerySet,
     InstalledWidgetsDashboardWidgetOrderManager,
+    PolymorphicCurrentSiteManager,
     SchoolTermQuerySet,
     UninstallRenitentPolymorphicManager,
 )
@@ -1588,7 +1589,7 @@ class BirthdayEvent(CalendarEventMixin):
         return qs
 
 
-class Holiday(CalendarEventMixin, ExtensibleModel):
+class Holiday(CalendarEvent):
     name = "holidays"
     verbose_name = _("Holidays")
 
@@ -1600,19 +1601,9 @@ class Holiday(CalendarEventMixin, ExtensibleModel):
     def value_description(cls, reference_object):
         return ""
 
-    @classmethod
-    def value_start_datetime(cls, reference_object):
-        return reference_object.date_start
-
-    @classmethod
-    def value_end_datetime(cls, reference_object):
-        return reference_object.date_end + timedelta(days=1)
-
-    objects = CurrentSiteManagerWithoutMigrations.from_queryset(HolidayQuerySet)()
+    objects = PolymorphicCurrentSiteManager.from_queryset(HolidayQuerySet)()
 
     holiday_name = models.CharField(verbose_name=_("Name"), max_length=255)
-    date_start = models.DateField(verbose_name=_("Start date"))
-    date_end = models.DateField(verbose_name=_("End date"))
 
     def get_days(self) -> Iterator[date]:
         delta = self.date_end - self.date_start
@@ -1645,14 +1636,9 @@ class Holiday(CalendarEventMixin, ExtensibleModel):
 
         return per_weekday
 
-    @classmethod
-    def get_objects(cls, request):
-        return cls.objects.all()
-
     def __str__(self) -> str:
         return self.holiday_name
 
     class Meta:
-        ordering = ["date_start"]
         verbose_name = _("Holiday")
         verbose_name_plural = _("Holidays")