diff --git a/district/migrations/0218_auto_20240601_1530.py b/district/migrations/0218_auto_20240601_1530.py
index a25b581a37d50477631432fa86a45c431bbcd69b..d1c8953e0550ab6207c82e77e0486985c88ca698 100644
--- a/district/migrations/0218_auto_20240601_1530.py
+++ b/district/migrations/0218_auto_20240601_1530.py
@@ -4,6 +4,7 @@ import wagtail
 from django.apps import apps as base_apps
 from django.contrib.contenttypes.management import create_contenttypes
 from django.db import migrations, transaction
+from django.db.utils import IntegrityError
 from wagtail.blocks import CharBlock, RichTextBlock, StreamBlock, StructBlock
 
 from district.blocks import (
@@ -18,518 +19,525 @@ from shared.blocks import SocialLinkBlock
 
 
 def migrate_programs(apps, schema_editor):
-    # Copy this block manually here, as it has been changed in future migrations.
-    class ProgramGroupWithCandidatesBlock(StructBlock):
-        title = CharBlock(
-            label="Název programu",
-            help_text="Např. 'Krajské volby 2024', 'Evropské volby 2024', ...",
-        )
-
-        preamble_content = RichTextBlock(
-            label="Preambule",
-            help_text="Text, který se zobrazí před přepínačem mezi kandidáty a programem.",
-            required=False,
-        )
-
-        primary_candidates = CandidateListBlock(
-            label="Osoby na čele kandidátky",
-            help_text="Zobrazí se ve velkých blocích na začátku stránky.",
-        )
-
-        secondary_candidates = CandidateSecondaryListBlock(
-            label="Ostatní osoby na kandidátce",
-            help_text="Zobrazí se v kompaktním seznamu pod čelem kandidátky.",
-        )
-
-        program = StreamBlock(
-            [
-                ("program_group", ProgramGroupBlock()),
-                ("program_group_crossroad", ProgramGroupBlockCrossroad()),
-                ("program_group_popout", ProgramGroupBlockPopout()),
-                (
-                    "carousel_program",
-                    CarouselProgramBlock(
-                        template="styleguide2/includes/molecules/program/program_block.html"
-                    ),
-                ),
-            ]
-        )
+    try:
+        with transaction.atomic():
+            # Copy this block manually here, as it has been changed in future migrations.
+            class ProgramGroupWithCandidatesBlock(StructBlock):
+                title = CharBlock(
+                    label="Název programu",
+                    help_text="Např. 'Krajské volby 2024', 'Evropské volby 2024', ...",
+                )
+
+                preamble_content = RichTextBlock(
+                    label="Preambule",
+                    help_text="Text, který se zobrazí před přepínačem mezi kandidáty a programem.",
+                    required=False,
+                )
+
+                primary_candidates = CandidateListBlock(
+                    label="Osoby na čele kandidátky",
+                    help_text="Zobrazí se ve velkých blocích na začátku stránky.",
+                )
+
+                secondary_candidates = CandidateSecondaryListBlock(
+                    label="Ostatní osoby na kandidátce",
+                    help_text="Zobrazí se v kompaktním seznamu pod čelem kandidátky.",
+                )
+
+                program = StreamBlock(
+                    [
+                        ("program_group", ProgramGroupBlock()),
+                        ("program_group_crossroad", ProgramGroupBlockCrossroad()),
+                        ("program_group_popout", ProgramGroupBlockPopout()),
+                        (
+                            "carousel_program",
+                            CarouselProgramBlock(
+                                template="styleguide2/includes/molecules/program/program_block.html"
+                            ),
+                        ),
+                    ]
+                )
 
-    # Get the models
-    DistrictHomePage = apps.get_model("district", "DistrictHomePage")
+            # Get the models
+            DistrictHomePage = apps.get_model("district", "DistrictHomePage")
 
-    # Update content types, as they may not yet have been created.
-    # This is very ugly, but must be done.
-    create_contenttypes(base_apps.get_app_config("district"))
+            # Update content types, as they may not yet have been created.
+            # This is very ugly, but must be done.
+            create_contenttypes(base_apps.get_app_config("district"))
 
-    DistrictElectionRootPage = apps.get_model("district", "DistrictElectionRootPage")
-    DistrictElectionCampaignPage = apps.get_model(
-        "district", "DistrictElectionCampaignPage"
-    )
+            DistrictElectionRootPage = apps.get_model("district", "DistrictElectionRootPage")
+            DistrictElectionCampaignPage = apps.get_model(
+                "district", "DistrictElectionCampaignPage"
+            )
 
-    DistrictElectionProgramPage = apps.get_model(
-        "district", "DistrictElectionProgramPage"
-    )
-    DistrictPostElectionStrategyPage = apps.get_model(
-        "district", "DistrictPostElectionStrategyPage"
-    )
+            DistrictElectionProgramPage = apps.get_model(
+                "district", "DistrictElectionProgramPage"
+            )
+            DistrictPostElectionStrategyPage = apps.get_model(
+                "district", "DistrictPostElectionStrategyPage"
+            )
 
-    DistrictNewProgramPage = apps.get_model("district", "DistrictNewProgramPage")
+            DistrictNewProgramPage = apps.get_model("district", "DistrictNewProgramPage")
 
-    Locale = apps.get_model("wagtailcore", "Locale")
+            Locale = apps.get_model("wagtailcore", "Locale")
 
-    DistrictPersonPage = apps.get_model("district", "DistrictPersonPage")
-    DistrictPeoplePage = apps.get_model("district", "DistrictPeoplePage")
+            DistrictPersonPage = apps.get_model("district", "DistrictPersonPage")
+            DistrictPeoplePage = apps.get_model("district", "DistrictPeoplePage")
 
-    # Get the default locale
-    default_locale = Locale.objects.first()
+            # Get the default locale
+            default_locale = Locale.objects.first()
 
-    Page = apps.get_model("wagtailcore", "Page")
+            Page = apps.get_model("wagtailcore", "Page")
 
-    ContentType = apps.get_model("contenttypes", "ContentType")
+            ContentType = apps.get_model("contenttypes", "ContentType")
 
-    try:
-        root_page_content_type = ContentType.objects.get(
-            app_label="district", model="districtelectionrootpage"
-        )
-        campaign_page_content_type = ContentType.objects.get(
-            app_label="district", model="districtelectioncampaignpage"
-        )
-
-        people_page_content_type = ContentType.objects.get(
-            app_label="district", model="districtpeoplepage"
-        )
-
-        program_page_content_type = ContentType.objects.get(
-            app_label="district", model="districtelectionprogrampage"
-        )
-        program_post_election_strategy_content_type = ContentType.objects.get(
-            app_label="district", model="districtpostelectionstrategypage"
-        )
-
-        new_program_page_content_type = ContentType.objects.get(
-            app_label="district", model="districtnewprogrampage"
-        )
-    except ContentType.DoesNotExist:
-        # This is a fresh instance and old models don't need to be migrated.
-        # Not beautiful, but shouldn't cause any trouble.
-        return
-
-    # Function to get children of a certain type
-    def get_children_of_type(model, parent_page, content_type):
-        return model.objects.filter(
-            path__startswith=parent_page.path,
-            depth=parent_page.depth + 1,
-            content_type=content_type,
-        )
-
-    for home_page in DistrictHomePage.objects.all():
-        # Create a new program page, even if this DistrictHomePage will
-        # end up having no programs.
-
-        max_path_page = (
-            Page.objects.filter(
-                path__startswith=home_page.path, depth=home_page.depth + 1
-            )
-            .order_by("-path")
-            .first()
-        )
-
-        if max_path_page:
-            max_path = max_path_page.path
-            next_path_suffix = (
-                int(max_path[-4:], 36) + 1
-            )  # Base-36 to handle alphanumeric paths
-            next_path = (
-                max_path[:-4] + f"{next_path_suffix:04X}"
-            )  # Convert back to base-36
-        else:
-            next_path = home_page.path + "0001"
-
-        # Create the new program page
-        with transaction.atomic():
-            new_program_page = DistrictNewProgramPage(
-                title="Programy",
-                slug="programy",  # Make sure the slug is unique among siblings
-                path=next_path,
-                depth=home_page.depth + 1,
-                numchild=0,
-                content_type_id=new_program_page_content_type.id,
-                locale_id=default_locale.id,
-            )
-            new_program_page.save()
-
-            # Update numchild on the home page
-            home_page.numchild = home_page.numchild + 1
-            home_page.save(update_fields=["numchild"])
-
-        # Iterate over all child DistrictElectionRootPage instances
-        for election_root_page in get_children_of_type(
-            DistrictElectionRootPage, home_page, root_page_content_type
-        ):
-            # Get the children of type DistrictElectionCampaignPage
-            campaign_pages = get_children_of_type(
-                DistrictElectionCampaignPage,
-                election_root_page,
-                campaign_page_content_type,
-            )
+            try:
+                root_page_content_type = ContentType.objects.get(
+                    app_label="district", model="districtelectionrootpage"
+                )
+                campaign_page_content_type = ContentType.objects.get(
+                    app_label="district", model="districtelectioncampaignpage"
+                )
 
-            for campaign_page in campaign_pages:
-                # Data for a single program
-
-                program_data = {
-                    # Title
-                    "title": "",  # Done
-                    "order": 0,
-                    # Post-election
-                    "post_election_strategies": [],
-                    # Candidates
-                    "candidate_list_number": "",
-                    "candidate_list_title": "",  # Done
-                    "candidate_pages": [],  # Done
-                    "candidate_blocks": [],  # Done
-                    "combined_candidates": [],  # Done
-                    "primary_candidate_count": 0,  # Done
-                    # Program
-                    "program_title": "",
-                    "program_points": [],
-                    "program_is_inline": False,
-                    "program_content_before": "",  # Done
-                    # Misc.
-                    "funding_info": "",
-                }
-
-                program_data["title"] = (
-                    election_root_page.title
-                    if election_root_page.title
-                    else campaign_page.title
+                people_page_content_type = ContentType.objects.get(
+                    app_label="district", model="districtpeoplepage"
                 )
 
-                program_data["order"] = campaign_page.order
+                program_page_content_type = ContentType.objects.get(
+                    app_label="district", model="districtelectionprogrampage"
+                )
+                program_post_election_strategy_content_type = ContentType.objects.get(
+                    app_label="district", model="districtpostelectionstrategypage"
+                )
 
-                program_data["candidate_list_number"] = campaign_page.number
-                program_data["candidate_list_title"] = (
-                    campaign_page.candidate_list_title
-                    if campaign_page.candidate_list_title
-                    else campaign_page.title
+                new_program_page_content_type = ContentType.objects.get(
+                    app_label="district", model="districtnewprogrampage"
+                )
+            except ContentType.DoesNotExist:
+                # This is a fresh instance and old models don't need to be migrated.
+                # Not beautiful, but shouldn't cause any trouble.
+                return
+
+            # Function to get children of a certain type
+            def get_children_of_type(model, parent_page, content_type):
+                return model.objects.filter(
+                    path__startswith=parent_page.path,
+                    depth=parent_page.depth + 1,
+                    content_type=content_type,
                 )
 
-                program_data["program_title"] = (
-                    campaign_page.program_point_list_title
-                    if campaign_page.program_point_list_title
-                    else campaign_page.title
+            for home_page in DistrictHomePage.objects.all():
+                # Create a new program page, even if this DistrictHomePage will
+                # end up having no programs.
+
+                max_path_page = (
+                    Page.objects.filter(
+                        path__startswith=home_page.path, depth=home_page.depth + 1
+                    )
+                    .order_by("-path")
+                    .first()
                 )
 
-                program_data[
-                    "program_is_inline"
-                ] = campaign_page.show_program_points_inline
+                if max_path_page:
+                    max_path = max_path_page.path
+                    next_path_suffix = (
+                        int(max_path[-4:], 36) + 1
+                    )  # Base-36 to handle alphanumeric paths
+                    next_path = (
+                        max_path[:-4] + f"{next_path_suffix:04X}"
+                    )  # Convert back to base-36
+                else:
+                    next_path = home_page.path + "0001"
+
+                # Create the new program page
+                with transaction.atomic():
+                    new_program_page = DistrictNewProgramPage(
+                        title="Programy",
+                        slug="programy",  # Make sure the slug is unique among siblings
+                        path=next_path,
+                        depth=home_page.depth + 1,
+                        numchild=0,
+                        content_type_id=new_program_page_content_type.id,
+                        locale_id=default_locale.id,
+                    )
+                    new_program_page.save()
 
-                program_data["funding_info"] = campaign_page.campaign_funding_info
+                    # Update numchild on the home page
+                    home_page.numchild = home_page.numchild + 1
+                    home_page.save(update_fields=["numchild"])
 
-                position = 0
+                # Iterate over all child DistrictElectionRootPage instances
+                for election_root_page in get_children_of_type(
+                    DistrictElectionRootPage, home_page, root_page_content_type
+                ):
+                    # Get the children of type DistrictElectionCampaignPage
+                    campaign_pages = get_children_of_type(
+                        DistrictElectionCampaignPage,
+                        election_root_page,
+                        campaign_page_content_type,
+                    )
 
-                # Parse candidates from blocks
-                for candidate_list_block in campaign_page.candidates.get_prep_value():
-                    candidate_list = candidate_list_block["value"]
+                    for campaign_page in campaign_pages:
+                        # Data for a single program
+
+                        program_data = {
+                            # Title
+                            "title": "",  # Done
+                            "order": 0,
+                            # Post-election
+                            "post_election_strategies": [],
+                            # Candidates
+                            "candidate_list_number": "",
+                            "candidate_list_title": "",  # Done
+                            "candidate_pages": [],  # Done
+                            "candidate_blocks": [],  # Done
+                            "combined_candidates": [],  # Done
+                            "primary_candidate_count": 0,  # Done
+                            # Program
+                            "program_title": "",
+                            "program_points": [],
+                            "program_is_inline": False,
+                            "program_content_before": "",  # Done
+                            # Misc.
+                            "funding_info": "",
+                        }
 
-                    program_data["primary_candidate_count"] = candidate_list[
-                        "candidate_list_big_count"
-                    ]
+                        program_data["title"] = (
+                            election_root_page.title
+                            if election_root_page.title
+                            else campaign_page.title
+                        )
 
-                    for candidate in candidate_list["candidate_list"]:
-                        if candidate["type"] == "person_page":
-                            if (
-                                DistrictPersonPage.objects.filter(
-                                    id=candidate["value"]
-                                ).first()
-                                is None
-                            ):
-                                # We have nothing to do here, this page ID is either unfilled or points to a missing page
-                                continue
-
-                            position = position + 1
-
-                            candidate_data = {
-                                "position": position,
-                                "page": DistrictPersonPage.objects.filter(
-                                    id=candidate["value"]
-                                ).first(),
-                            }
+                        program_data["order"] = campaign_page.order
 
-                            program_data["candidate_pages"].append(candidate_data)
-                            program_data["combined_candidates"].append(candidate_data)
+                        program_data["candidate_list_number"] = campaign_page.number
+                        program_data["candidate_list_title"] = (
+                            campaign_page.candidate_list_title
+                            if campaign_page.candidate_list_title
+                            else campaign_page.title
+                        )
 
-                            continue
+                        program_data["program_title"] = (
+                            campaign_page.program_point_list_title
+                            if campaign_page.program_point_list_title
+                            else campaign_page.title
+                        )
 
-                        elif candidate["type"] == "person_blocks":
-                            position = position + 1
+                        program_data[
+                            "program_is_inline"
+                        ] = campaign_page.show_program_points_inline
 
-                            program_data["candidate_blocks"].append(
-                                {"position": position, "data": candidate["value"]}
-                            )
+                        program_data["funding_info"] = campaign_page.campaign_funding_info
 
-                # Parse program points
-                program_pages = get_children_of_type(
-                    DistrictElectionProgramPage,
-                    campaign_page,
-                    program_page_content_type,
-                )
+                        position = 0
 
-                for program_page in program_pages:
-                    program_data["program_points"].append(
-                        {
-                            "title": program_page.title,  # Done
-                            "guarantor_page": program_page.guarantor,  # Done
-                            "image": program_page.image,  # Ignoring
-                            "perex": program_page.perex,  # Done
-                            "content": program_page.content,  # Done
-                            "funding_info": program_page.campaign_funding_info,  # TODO: Ignoring?
-                        }
-                    )
+                        # Parse candidates from blocks
+                        for candidate_list_block in campaign_page.candidates.get_prep_value():
+                            candidate_list = candidate_list_block["value"]
 
-                # Parse post-election strategies
-                post_election_strategy_pages = get_children_of_type(
-                    DistrictPostElectionStrategyPage,
-                    election_root_page,
-                    program_post_election_strategy_content_type,
-                )
+                            program_data["primary_candidate_count"] = candidate_list[
+                                "candidate_list_big_count"
+                            ]
 
-                for post_election_strategy_page in post_election_strategy_pages:
-                    program_data["post_election_strategies"].append(
-                        {
-                            "perex": post_election_strategy_page.perex,
-                        }
-                    )
+                            for candidate in candidate_list["candidate_list"]:
+                                if candidate["type"] == "person_page":
+                                    if (
+                                        DistrictPersonPage.objects.filter(
+                                            id=candidate["value"]
+                                        ).first()
+                                        is None
+                                    ):
+                                        # We have nothing to do here, this page ID is either unfilled or points to a missing page
+                                        continue
 
-                # If there's no program data, skip this iteration.
-                if (
-                    len(program_data["candidate_pages"]) == 0
-                    and len(program_data["candidate_blocks"]) == 0
-                    and len(program_data["program_points"]) == 0
-                ):
-                    continue  # Do nothing for these
+                                    position = position + 1
 
-                parent_people_page = get_children_of_type(
-                    DistrictPeoplePage, home_page, people_page_content_type
-                )
+                                    candidate_data = {
+                                        "position": position,
+                                        "page": DistrictPersonPage.objects.filter(
+                                            id=candidate["value"]
+                                        ).first(),
+                                    }
 
-                parent_people_page = parent_people_page.first()
+                                    program_data["candidate_pages"].append(candidate_data)
+                                    program_data["combined_candidates"].append(candidate_data)
 
-                # Create corresponding pages for candidate blocks with no pages
-                for candidate_block in program_data["candidate_blocks"]:
-                    if parent_people_page is None:
-                        break  # We can't do anything here
+                                    continue
 
-                    social_links = []
+                                elif candidate["type"] == "person_blocks":
+                                    position = position + 1
 
-                    if candidate_block["data"]["facebook_url"]:
-                        social_links.append(
-                            SocialLinkBlock().to_python(
-                                {
-                                    "icon": "ico--facebook",
-                                    "text": "Facebook",
-                                    "link": candidate_block["data"]["facebook_url"],
-                                }
-                            )
+                                    program_data["candidate_blocks"].append(
+                                        {"position": position, "data": candidate["value"]}
+                                    )
+
+                        # Parse program points
+                        program_pages = get_children_of_type(
+                            DistrictElectionProgramPage,
+                            campaign_page,
+                            program_page_content_type,
                         )
 
-                    if candidate_block["data"]["instagram_url"]:
-                        social_links.append(
-                            SocialLinkBlock().to_python(
+                        for program_page in program_pages:
+                            program_data["program_points"].append(
                                 {
-                                    "icon": "ico--instagram",
-                                    "text": "Instagram",
-                                    "link": candidate_block["data"]["instagram_url"],
+                                    "title": program_page.title,  # Done
+                                    "guarantor_page": program_page.guarantor,  # Done
+                                    "image": program_page.image,  # Ignoring
+                                    "perex": program_page.perex,  # Done
+                                    "content": program_page.content,  # Done
+                                    "funding_info": program_page.campaign_funding_info,  # TODO: Ignoring?
                                 }
                             )
+
+                        # Parse post-election strategies
+                        post_election_strategy_pages = get_children_of_type(
+                            DistrictPostElectionStrategyPage,
+                            election_root_page,
+                            program_post_election_strategy_content_type,
                         )
 
-                    if candidate_block["data"]["twitter_url"]:
-                        social_links.append(
-                            SocialLinkBlock().to_python(
+                        for post_election_strategy_page in post_election_strategy_pages:
+                            program_data["post_election_strategies"].append(
                                 {
-                                    "icon": "ico--twitter",
-                                    "text": "Twitter",
-                                    "link": candidate_block["data"]["twitter_url"],
+                                    "perex": post_election_strategy_page.perex,
                                 }
                             )
+
+                        # If there's no program data, skip this iteration.
+                        if (
+                            len(program_data["candidate_pages"]) == 0
+                            and len(program_data["candidate_blocks"]) == 0
+                            and len(program_data["program_points"]) == 0
+                        ):
+                            continue  # Do nothing for these
+
+                        parent_people_page = get_children_of_type(
+                            DistrictPeoplePage, home_page, people_page_content_type
                         )
 
-                    if candidate_block["data"]["youtube_url"]:
-                        social_links.append(
-                            SocialLinkBlock().to_python(
-                                {
-                                    "icon": "ico--youtube",
-                                    "text": "YouTube",
-                                    "link": candidate_block["data"]["youtube_url"],
-                                }
+                        parent_people_page = parent_people_page.first()
+
+                        # Create corresponding pages for candidate blocks with no pages
+                        for candidate_block in program_data["candidate_blocks"]:
+                            if parent_people_page is None:
+                                break  # We can't do anything here
+
+                            social_links = []
+
+                            if candidate_block["data"]["facebook_url"]:
+                                social_links.append(
+                                    SocialLinkBlock().to_python(
+                                        {
+                                            "icon": "ico--facebook",
+                                            "text": "Facebook",
+                                            "link": candidate_block["data"]["facebook_url"],
+                                        }
+                                    )
+                                )
+
+                            if candidate_block["data"]["instagram_url"]:
+                                social_links.append(
+                                    SocialLinkBlock().to_python(
+                                        {
+                                            "icon": "ico--instagram",
+                                            "text": "Instagram",
+                                            "link": candidate_block["data"]["instagram_url"],
+                                        }
+                                    )
+                                )
+
+                            if candidate_block["data"]["twitter_url"]:
+                                social_links.append(
+                                    SocialLinkBlock().to_python(
+                                        {
+                                            "icon": "ico--twitter",
+                                            "text": "Twitter",
+                                            "link": candidate_block["data"]["twitter_url"],
+                                        }
+                                    )
+                                )
+
+                            if candidate_block["data"]["youtube_url"]:
+                                social_links.append(
+                                    SocialLinkBlock().to_python(
+                                        {
+                                            "icon": "ico--youtube",
+                                            "text": "YouTube",
+                                            "link": candidate_block["data"]["youtube_url"],
+                                        }
+                                    )
+                                )
+
+                            if candidate_block["data"]["flickr_url"]:
+                                social_links.append(
+                                    SocialLinkBlock().to_python(
+                                        {
+                                            "icon": "ico--flickr",
+                                            "text": "Flickr",
+                                            "link": candidate_block["data"]["flickr_url"],
+                                        }
+                                    )
+                                )
+
+                            max_path_page = (
+                                Page.objects.filter(
+                                    path__startswith=people_page.path,
+                                    depth=parent_people_page.depth + 1,
+                                )
+                                .order_by("-path")
+                                .first()
                             )
-                        )
 
-                    if candidate_block["data"]["flickr_url"]:
-                        social_links.append(
-                            SocialLinkBlock().to_python(
+                            if max_path_page:
+                                max_path = max_path_page.path
+                                next_path_suffix = (
+                                    int(max_path[-4:], 36) + 1
+                                )  # Base-36 to handle alphanumeric paths
+                                next_path = (
+                                    max_path[:-4] + f"{next_path_suffix:04X}"
+                                )  # Convert back to base-36
+                            else:
+                                next_path = parent_people_page.path + "0001"
+
+                            with transaction.atomic():
+                                candidate_page = DistrictPersonPage(
+                                    title=candidate_block["data"]["title"],
+                                    job=candidate_block["data"]["job"],
+                                    profile_image_id=candidate_block["data"]["profile_photo"],
+                                    email=candidate_block["data"]["email"],
+                                    city=candidate_block["data"]["city"],
+                                    age=candidate_block["data"]["age"],
+                                    is_pirate=candidate_block["data"]["is_pirate"],
+                                    other_party=candidate_block["data"]["other_party"],
+                                    other_party_logo_id=candidate_block["data"][
+                                        "other_party_logo"
+                                    ],
+                                    social_links=social_links,
+                                    content_type_id=people_page_content_type.id,
+                                    locale_id=default_locale.id,
+                                )
+
+                                candidate_page.numchild = candidate_page.numchild + 1
+                                candidate_page.save(update_fields=["numchild"])
+
+                            program_data["combined_candidates"].append(
                                 {
-                                    "icon": "ico--flickr",
-                                    "text": "Flickr",
-                                    "link": candidate_block["data"]["flickr_url"],
+                                    "position": candidate_block["position"],
+                                    "page": candidate_page,
                                 }
                             )
-                        )
 
-                    max_path_page = (
-                        Page.objects.filter(
-                            path__startswith=people_page.path,
-                            depth=parent_people_page.depth + 1,
+                        # Sort candidates
+                        program_data["combined_candidates"] = sorted(
+                            program_data["combined_candidates"],
+                            key=lambda value: value["position"],
                         )
-                        .order_by("-path")
-                        .first()
-                    )
 
-                    if max_path_page:
-                        max_path = max_path_page.path
-                        next_path_suffix = (
-                            int(max_path[-4:], 36) + 1
-                        )  # Base-36 to handle alphanumeric paths
-                        next_path = (
-                            max_path[:-4] + f"{next_path_suffix:04X}"
-                        )  # Convert back to base-36
-                    else:
-                        next_path = parent_people_page.path + "0001"
-
-                    with transaction.atomic():
-                        candidate_page = DistrictPersonPage(
-                            title=candidate_block["data"]["title"],
-                            job=candidate_block["data"]["job"],
-                            profile_image_id=candidate_block["data"]["profile_photo"],
-                            email=candidate_block["data"]["email"],
-                            city=candidate_block["data"]["city"],
-                            age=candidate_block["data"]["age"],
-                            is_pirate=candidate_block["data"]["is_pirate"],
-                            other_party=candidate_block["data"]["other_party"],
-                            other_party_logo_id=candidate_block["data"][
-                                "other_party_logo"
-                            ],
-                            social_links=social_links,
-                            content_type_id=people_page_content_type.id,
-                            locale_id=default_locale.id,
-                        )
+                        # Create candidate blocks
+                        primary_candidates = []
+                        secondary_candidates = []
+
+                        for position, candidate in enumerate(
+                            program_data["combined_candidates"]
+                        ):
+                            if position <= program_data["primary_candidate_count"]:
+                                primary_candidates.append(
+                                    {  # CandidateBlock value for CandidateListBlock
+                                        "page": candidate["page"].id,
+                                        "description": (
+                                            candidate["page"].perex
+                                            if len(candidate["page"].perex) > 32
+                                            else (
+                                                candidate["page"].job
+                                                if candidate["page"].job
+                                                else candidate["page"].position
+                                            )
+                                        ),
+                                        "image": (
+                                            candidate["page"].profile_image.id
+                                            # Not sure why there is a need to check for the second condition.
+                                            # But, without it, the migration crashes on some images.
+                                            if candidate["page"].profile_image is not None
+                                            else 0
+                                        ),
+                                    }
+                                )
+                            else:
+                                secondary_candidates.append(
+                                    {  # SecondaryCandidateBlock value for CandidateSecondaryListBlock
+                                        "number": candidate["position"],
+                                        "page": candidate["page"].id,
+                                    }
+                                )
 
-                        candidate_page.numchild = candidate_page.numchild + 1
-                        candidate_page.save(update_fields=["numchild"])
+                        primary_candidates_block = {
+                            # Acts as CandidateListBlock
+                            "candidates": primary_candidates,
+                        }
 
-                    program_data["combined_candidates"].append(
-                        {
-                            "position": candidate_block["position"],
-                            "page": candidate_page,
+                        secondary_candidates_block = {
+                            # Acts as CandidateSecondaryListBlock
+                            "heading": "Další kandidáti",
+                            "candidates": secondary_candidates,
                         }
-                    )
 
-                # Sort candidates
-                program_data["combined_candidates"] = sorted(
-                    program_data["combined_candidates"],
-                    key=lambda value: value["position"],
-                )
+                        # if program_data["program_is_inline"]:
 
-                # Create candidate blocks
-                primary_candidates = []
-                secondary_candidates = []
+                        # There's no time left to set this up properly. We'll just use
+                        # inline points for everything, at least for now.
 
-                for position, candidate in enumerate(
-                    program_data["combined_candidates"]
-                ):
-                    if position <= program_data["primary_candidate_count"]:
-                        primary_candidates.append(
-                            {  # CandidateBlock value for CandidateListBlock
-                                "page": candidate["page"].id,
-                                "description": (
-                                    candidate["page"].perex
-                                    if len(candidate["page"].perex) > 32
-                                    else (
-                                        candidate["page"].job
-                                        if candidate["page"].job
-                                        else candidate["page"].position
-                                    )
-                                ),
-                                "image": (
-                                    candidate["page"].profile_image.id
-                                    # Not sure why there is a need to check for the second condition.
-                                    # But, without it, the migration crashes on some images.
-                                    if candidate["page"].profile_image is not None
-                                    else 0
-                                ),
+                        # Create program point blocks
+                        program_points = []
+
+                        for program_point in program_data["program_points"]:
+                            program_points.append(
+                                {  # Act as ProgramBlockPopout
+                                    "title": program_point["title"],
+                                    "content": str(program_point["content"]),
+                                    "guarantor": (
+                                        program_point["guarantor_page"].id
+                                        if program_point["guarantor_page"]
+                                        else None
+                                    ),
+                                }
+                            )
+
+                        program_categories = [
+                            {  # Act as ProgramPopoutCategory
+                                "name": program_data["candidate_list_title"],
+                                "point_list": program_points,
                             }
-                        )
-                    else:
-                        secondary_candidates.append(
-                            {  # SecondaryCandidateBlock value for CandidateSecondaryListBlock
-                                "number": candidate["position"],
-                                "page": candidate["page"].id,
+                        ]
+
+                        program_block = {
+                            "type": "program_group_popout",
+                            "value": {
+                                "title": program_data["program_title"],
+                                "categories": program_categories,
+                            },
+                        }
+
+                        # Finally, create a block for this program
+                        new_program_block = ProgramGroupWithCandidatesBlock().to_python(
+                            {
+                                "title": program_data["title"],
+                                "preamble_content": program_data["program_content_before"],
+                                "primary_candidates": primary_candidates_block,
+                                "secondary_candidates": secondary_candidates_block,
+                                "program": [program_block],
                             }
                         )
 
-                primary_candidates_block = {
-                    # Acts as CandidateListBlock
-                    "candidates": primary_candidates,
-                }
-
-                secondary_candidates_block = {
-                    # Acts as CandidateSecondaryListBlock
-                    "heading": "Další kandidáti",
-                    "candidates": secondary_candidates,
-                }
-
-                # if program_data["program_is_inline"]:
-
-                # There's no time left to set this up properly. We'll just use
-                # inline points for everything, at least for now.
-
-                # Create program point blocks
-                program_points = []
-
-                for program_point in program_data["program_points"]:
-                    program_points.append(
-                        {  # Act as ProgramBlockPopout
-                            "title": program_point["title"],
-                            "content": str(program_point["content"]),
-                            "guarantor": (
-                                program_point["guarantor_page"].id
-                                if program_point["guarantor_page"]
-                                else None
-                            ),
-                        }
-                    )
-
-                program_categories = [
-                    {  # Act as ProgramPopoutCategory
-                        "name": program_data["candidate_list_title"],
-                        "point_list": program_points,
-                    }
-                ]
-
-                program_block = {
-                    "type": "program_group_popout",
-                    "value": {
-                        "title": program_data["program_title"],
-                        "categories": program_categories,
-                    },
-                }
-
-                # Finally, create a block for this program
-                new_program_block = ProgramGroupWithCandidatesBlock().to_python(
-                    {
-                        "title": program_data["title"],
-                        "preamble_content": program_data["program_content_before"],
-                        "primary_candidates": primary_candidates_block,
-                        "secondary_candidates": secondary_candidates_block,
-                        "program": [program_block],
-                    }
-                )
+                        new_program_page.program.append(
+                            ("program_group_with_candidates", new_program_block)
+                        )
 
-                new_program_page.program.append(
-                    ("program_group_with_candidates", new_program_block)
-                )
-                new_program_page.save()
+                        new_program_page.save()
+    except Exception as e:
+        print(f"Ignoring exception during program page migration: {e}")
+        
+        pass
 
 
 class Migration(migrations.Migration):