diff --git a/calendar_utils/models.py b/calendar_utils/models.py
index 807b73f1ae4fe6752b90977c3be55712ba522d9e..733d1d0e60a9137d3c5a90ec15e6d1e977ef15ac 100644
--- a/calendar_utils/models.py
+++ b/calendar_utils/models.py
@@ -9,10 +9,6 @@ from django.core.validators import URLValidator, ValidationError
 from django.db import models
 from icalevents import icalevents
 from wagtail.admin.panels import FieldPanel
-from wagtail.models import Page
-from wagtailmetadata.models import MetadataPageMixin
-
-from shared.models import SubpageMixin
 
 from .parser import process_event_list
 
@@ -91,17 +87,10 @@ class CalendarMixin(models.Model):
     calendar = models.ForeignKey(
         Calendar, null=True, blank=True, on_delete=models.PROTECT
     )
-    calendar_page = models.ForeignKey(
-        "calendar_utils.CalendarPage",
-        verbose_name="Stránka s kalendářem",
-        on_delete=models.PROTECT,
-        null=True,
-        blank=True,
-    )
 
     @property
     def first_calendar_page(self):
-        return self._first_subpage_of_type(CalendarPage)
+        return self._first_subpage_of_type(CalendarPageMixin)
 
     class Meta:
         abstract = True
@@ -162,9 +151,9 @@ class CalendarMixin(models.Model):
         super().save(*args, **kwargs)
 
 
-class CalendarPage(SubpageMixin, MetadataPageMixin, CalendarMixin, Page):
+class CalendarPageMixin(CalendarMixin):
     """
-    Page for displaying full calendar
+    Page mixin for displaying full calendar
     """
 
     calendar_url = models.URLField(
@@ -173,41 +162,13 @@ class CalendarPage(SubpageMixin, MetadataPageMixin, CalendarMixin, Page):
 
     ### PANELS
 
-    content_panels = Page.content_panels + [
+    content_panels = [
         FieldPanel("calendar_url"),
     ]
 
     ### RELATIONS
 
-    parent_page_types = [
-        "district.DistrictCenterPage",
-        "district.DistrictHomePage",
-        "elections2021.Elections2021CalendarPage",
-        "senat_campaign.SenatCampaignHomePage",
-        "uniweb.UniwebHomePage",
-    ]
     subpage_types = []
 
-    ### OTHERS
-
-    def get_template(self, request):
-        """
-        Allows this template to dynamically load correct calendar_page, based on root page which helps it determine from
-        which project the page should be loaded
-        """
-        module = self.root_page.__class__.__module__  # Example: "district.module"
-        pathname = module.split(".")[0]  # Gets "district" from "district.module"
-        root = str(Path(__file__).parents[2])
-        project = root + "/majak"
-        return str(
-            Path(
-                project,
-                pathname,
-                "templates",
-                pathname,
-                pathname + "_calendar_page.html",
-            )
-        )
-
     class Meta:
-        verbose_name = "Stránka s kalendářem"
+        abstract = True
diff --git a/district/migrations/0107_districtcenterpage_calendar_page_and_more.py b/district/migrations/0107_districtcenterpage_calendar_page_and_more.py
deleted file mode 100644
index eab610a0f65318a5dd312b50b913f4b407cc0c65..0000000000000000000000000000000000000000
--- a/district/migrations/0107_districtcenterpage_calendar_page_and_more.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Generated by Django 4.1.6 on 2023-04-13 21:12
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("calendar_utils", "0005_calendarpage"),
-        ("district", "0106_alter_districtcrossroadpage_cards_content"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="districtcenterpage",
-            name="calendar_page",
-            field=models.ForeignKey(
-                blank=True,
-                null=True,
-                on_delete=django.db.models.deletion.PROTECT,
-                to="calendar_utils.calendarpage",
-                verbose_name="Stránka s kalendářem",
-            ),
-        ),
-        migrations.AddField(
-            model_name="districthomepage",
-            name="calendar_page",
-            field=models.ForeignKey(
-                blank=True,
-                null=True,
-                on_delete=django.db.models.deletion.PROTECT,
-                to="calendar_utils.calendarpage",
-                verbose_name="Stránka s kalendářem",
-            ),
-        ),
-    ]
diff --git a/district/migrations/0109_districtcalendarpage_and_more.py b/district/migrations/0109_districtcalendarpage_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..468fe20fc347018041b8569eda497c131381eb5a
--- /dev/null
+++ b/district/migrations/0109_districtcalendarpage_and_more.py
@@ -0,0 +1,92 @@
+# Generated by Django 4.1.8 on 2023-04-14 23:48
+
+import django.db.models.deletion
+import wagtailmetadata.models
+from django.db import migrations, models
+
+import shared.models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("wagtailimages", "0025_alter_image_file_alter_rendition_file"),
+        ("wagtailcore", "0083_workflowcontenttype"),
+        ("calendar_utils", "0004_auto_20220505_1228"),
+        ("district", "0108_alter_districtcenterpage_content_and_more"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="DistrictCalendarPage",
+            fields=[
+                (
+                    "page_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="wagtailcore.page",
+                    ),
+                ),
+                (
+                    "calendar_url",
+                    models.URLField(
+                        null=True, verbose_name="URL kalendáře ve formátu iCal"
+                    ),
+                ),
+                (
+                    "calendar",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        to="calendar_utils.calendar",
+                    ),
+                ),
+                (
+                    "search_image",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                        verbose_name="Search image",
+                    ),
+                ),
+            ],
+            options={
+                "verbose_name": "Stránka s kalendářem",
+            },
+            bases=(
+                shared.models.SubpageMixin,
+                wagtailmetadata.models.WagtailImageMetadataMixin,
+                "wagtailcore.page",
+                models.Model,
+            ),
+        ),
+        migrations.AddField(
+            model_name="districtcenterpage",
+            name="calendar_page",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                to="district.districtcalendarpage",
+                verbose_name="Stránka s kalendářem",
+            ),
+        ),
+        migrations.AddField(
+            model_name="districthomepage",
+            name="calendar_page",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                to="district.districtcalendarpage",
+                verbose_name="Stránka s kalendářem",
+            ),
+        ),
+    ]
diff --git a/district/models.py b/district/models.py
index bb7c591b6092473a1b99f76f174c2deb60bca731..bee7c79c174fa263727c2422b7d9f6bdd7a8d4aa 100644
--- a/district/models.py
+++ b/district/models.py
@@ -26,7 +26,7 @@ from wagtail.fields import RichTextField, StreamField
 from wagtail.models import Orderable, Page
 from wagtailmetadata.models import MetadataPageMixin
 
-from calendar_utils.models import CalendarMixin, CalendarPage
+from calendar_utils.models import CalendarMixin, CalendarPageMixin
 from maps_utils.blocks import MapPointBlock
 from maps_utils.const import (
     DEFAULT_MAP_STYLE,
@@ -77,6 +77,14 @@ class DistrictHomePage(
 ):
     ### FIELDS
 
+    calendar_page = models.ForeignKey(
+        "DistrictCalendarPage",
+        verbose_name="Stránka s kalendářem",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+    )
+
     subheader = StreamField(
         [
             ("header_full_size", FullSizeHeaderBlock()),
@@ -312,7 +320,7 @@ class DistrictHomePage(
         "district.DistrictProgramPage",
         "district.DistrictInteractiveProgramPage",
         "district.DistrictGeoFeatureCollectionPage",
-        "calendar_utils.CalendarPage",
+        "district.DistrictCalendarPage",
     ]
 
     ### OTHERS
@@ -1263,6 +1271,14 @@ class DistrictCenterPage(
 ):
     ### FIELDS
 
+    calendar_page = models.ForeignKey(
+        "DistrictCalendarPage",
+        verbose_name="Stránka s kalendářem",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+    )
+
     perex = models.TextField("Perex", blank=True, null=True)
     background_photo = models.ForeignKey(
         "wagtailimages.Image",
@@ -1320,7 +1336,7 @@ class DistrictCenterPage(
     ### RELATIONS
 
     parent_page_types = ["district.DistrictHomePage"]
-    subpage_types = ["calendar_utils.CalendarPage"]
+    subpage_types = ["district.DistrictCalendarPage"]
 
     ### OTHERS
 
@@ -1679,6 +1695,29 @@ def make_feature_index_cache_key(feature: "DistrictGeoFeatureDetailPage"):
     return f"DistrictGeoFeatureDetailPage::{feature.id}::index"
 
 
+class DistrictCalendarPage(SubpageMixin, MetadataPageMixin, CalendarPageMixin, Page):
+    """
+    Page for displaying full calendar
+    """
+
+    ### PANELS
+
+    content_panels = Page.content_panels + CalendarPageMixin.content_panels
+
+    ### RELATIONS
+
+    parent_page_types = [
+        "district.DistrictCenterPage",
+        "district.DistrictHomePage",
+    ]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Stránka s kalendářem"
+
+
 class DistrictGeoFeatureDetailPage(
     ExtendedMetadataPageMixin, MetadataPageMixin, SubpageMixin, Page, Orderable
 ):
diff --git a/senat_campaign/migrations/0011_senatcampaignhomepage_calendar_page.py b/senat_campaign/migrations/0011_senatcampaignhomepage_calendar_page.py
deleted file mode 100644
index 4b2c59e2410eac738b2dbbb7d347ac11df612138..0000000000000000000000000000000000000000
--- a/senat_campaign/migrations/0011_senatcampaignhomepage_calendar_page.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 4.1.6 on 2023-04-13 21:12
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("calendar_utils", "0005_calendarpage"),
-        ("senat_campaign", "0010_alter_senatcampaignhomepage_about_gallery_and_more"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="senatcampaignhomepage",
-            name="calendar_page",
-            field=models.ForeignKey(
-                blank=True,
-                null=True,
-                on_delete=django.db.models.deletion.PROTECT,
-                to="calendar_utils.calendarpage",
-                verbose_name="Stránka s kalendářem",
-            ),
-        ),
-    ]
diff --git a/uniweb/migrations/0040_uniwebhomepage_calendar_page.py b/uniweb/migrations/0040_uniwebhomepage_calendar_page.py
deleted file mode 100644
index e90815f840cd4d3723ef104f84e463cd8812c31c..0000000000000000000000000000000000000000
--- a/uniweb/migrations/0040_uniwebhomepage_calendar_page.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 4.1.6 on 2023-04-13 21:12
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("calendar_utils", "0005_calendarpage"),
-        ("uniweb", "0039_alter_uniwebhomepage_top_menu"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="uniwebhomepage",
-            name="calendar_page",
-            field=models.ForeignKey(
-                blank=True,
-                null=True,
-                on_delete=django.db.models.deletion.PROTECT,
-                to="calendar_utils.calendarpage",
-                verbose_name="Stránka s kalendářem",
-            ),
-        ),
-    ]
diff --git a/calendar_utils/migrations/0005_calendarpage.py b/uniweb/migrations/0042_uniwebcalendarpage_uniwebhomepage_calendar_page.py
similarity index 79%
rename from calendar_utils/migrations/0005_calendarpage.py
rename to uniweb/migrations/0042_uniwebcalendarpage_uniwebhomepage_calendar_page.py
index cbeddbd4fdd8d31586044734ac82ebc902710db5..1a80559648f39f50f4a0f0c1c97808008c15ea7d 100644
--- a/calendar_utils/migrations/0005_calendarpage.py
+++ b/uniweb/migrations/0042_uniwebcalendarpage_uniwebhomepage_calendar_page.py
@@ -1,4 +1,4 @@
-# Generated by Django 4.1.6 on 2023-04-13 21:12
+# Generated by Django 4.1.8 on 2023-04-14 23:48
 
 import django.db.models.deletion
 import wagtailmetadata.models
@@ -12,11 +12,12 @@ class Migration(migrations.Migration):
         ("wagtailimages", "0025_alter_image_file_alter_rendition_file"),
         ("wagtailcore", "0083_workflowcontenttype"),
         ("calendar_utils", "0004_auto_20220505_1228"),
+        ("uniweb", "0041_alter_uniwebflexiblepage_content_and_more"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name="CalendarPage",
+            name="UniwebCalendarPage",
             fields=[
                 (
                     "page_ptr",
@@ -44,16 +45,6 @@ class Migration(migrations.Migration):
                         to="calendar_utils.calendar",
                     ),
                 ),
-                (
-                    "calendar_page",
-                    models.ForeignKey(
-                        blank=True,
-                        null=True,
-                        on_delete=django.db.models.deletion.PROTECT,
-                        to="calendar_utils.calendarpage",
-                        verbose_name="Stránka s kalendářem",
-                    ),
-                ),
                 (
                     "search_image",
                     models.ForeignKey(
@@ -76,4 +67,15 @@ class Migration(migrations.Migration):
                 models.Model,
             ),
         ),
+        migrations.AddField(
+            model_name="uniwebhomepage",
+            name="calendar_page",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                to="uniweb.uniwebcalendarpage",
+                verbose_name="Stránka s kalendářem",
+            ),
+        ),
     ]
diff --git a/uniweb/models.py b/uniweb/models.py
index 3d419da6e6d96cef5cfd51a55eff502f747a0e10..2ef00fde80648f0bcded7c820a7979e70311667c 100644
--- a/uniweb/models.py
+++ b/uniweb/models.py
@@ -310,6 +310,14 @@ class UniwebHomePage(
 ):
     ### FIELDS
 
+    calendar_page = models.ForeignKey(
+        "UniwebCalendarPage",
+        verbose_name="Stránka s kalendářem",
+        on_delete=models.PROTECT,
+        null=True,
+        blank=True,
+    )
+
     content = StreamField(
         CONTENT_STREAM_BLOCKS + [("newsletter", NewsletterSubscriptionBlock())],
         verbose_name="obsah stránky",
@@ -421,7 +429,7 @@ class UniwebHomePage(
         "uniweb.UniwebArticlesIndexPage",
         "uniweb.UniwebFormPage",
         "uniweb.UniwebPeoplePage",
-        "calendar_utils.CalendarPage",
+        "uniweb.UniwebCalendarPage",
     ]
 
     ### OTHERS
@@ -478,6 +486,28 @@ class UniwebFlexiblePage(
         verbose_name = "Flexibilní stránka"
 
 
+class UniwebCalendarPage(SubpageMixin, MetadataPageMixin, CalendarPageMixin, Page):
+    """
+    Page for displaying full calendar
+    """
+
+    ### PANELS
+
+    content_panels = Page.content_panels + CalendarPageMixin.content_panels
+
+    ### RELATIONS
+
+    parent_page_types = [
+        "uniweb.UniwebHomePage",
+    ]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Stránka s kalendářem"
+
+
 class UniwebArticlesIndexPage(
     Page, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin
 ):