Skip to content
Snippets Groups Projects
Select Git revision
  • 650f89005a182f729f02ac2fda01a972026d3e30
  • test default protected
  • master protected
  • feat/custom-css
  • feat/redesign-improvements-10
  • feat/redesign-improvements-8
  • feat/redesign-fixes-3
  • feat/pirstan-changes
  • feat/separate-import-thread
  • feat/dary-improvements
  • features/add-pdf-page
  • features/add-typed-table
  • features/fix-broken-calendar-categories
  • features/add-embed-to-articles
  • features/create-mastodon-feed-block
  • features/add-custom-numbering-for-candidates
  • features/add-timeline
  • features/create-wordcloud-from-article-page
  • features/create-collapsible-extra-legal-info
  • features/extend-hero-banner
  • features/add-link-to-images
21 results

0022_remove_districtelectionpage_strategy_page.py

Blame
  • models.py 24.87 KiB
    from functools import cached_property
    
    from django.conf import settings
    from django.core.cache import cache
    from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
    from django.db import models
    from django.http import HttpResponseRedirect
    from django.shortcuts import redirect
    from django.template.response import TemplateResponse
    from modelcluster.fields import ParentalKey
    from wagtail.admin.panels import (
        FieldPanel,
        InlinePanel,
        MultiFieldPanel,
        ObjectList,
        PublishingPanel,
        TabbedInterface,
    )
    from wagtail.fields import RichTextField, StreamField
    from wagtail.images.blocks import ImageChooserBlock
    from wagtail.models import Orderable, Page
    from wagtailmetadata.models import MetadataPageMixin
    
    from shared_legacy.models import (
        ExtendedMetadataHomePageMixin,
        ExtendedMetadataPageMixin,
        SubpageMixin,
    )
    from shared_legacy.utils import get_subpage_url, make_promote_panels
    from tuning import admin_help
    
    from .blocks import (
        CrowdfundingRewardBlock,
        CustomContentBlock,
        CustomLinkBlock,
        DistrictDonationBlock,
        MenuItemBlock,
        MenuParentBlock,
        PartySupportFormBlock,
        ProjectIndexBlock,
    )
    from .forms import DonateForm
    from .utils import get_donated_amount_from_api
    
    
    class DonateFormMixin(models.Model):
        """Pages which has donate form. Must be in class definition before Page!"""
    
        portal_project_id = models.IntegerField(
            "ID projektu v darovacím portálu", blank=True, null=True
        )
    
        class Meta:
            abstract = True
    
        def serve(self, request, *args, **kwargs):
            if request.method == "POST":
                form = DonateForm(request.POST)
                if form.is_valid():
                    url = form.get_redirect_url()
                    return redirect(url)
            return super().serve(request, *args, **kwargs)
    
        @property
        def show_donate_form(self):
            return bool(self.portal_project_id)
    
    
    class DonateFormAmountsMixin(models.Model):
        """Amounts setup for donate forms."""
    
        FIRST = 1
        SECOND = 2
        THIRD = 3
        FOURTH = 4
        FORM_CHOICES = [
            (FIRST, "první"),
            (SECOND, "druhá"),
            (THIRD, "třetí"),
            (FOURTH, "čtvrtá"),
        ]
    
        form_amount_1 = models.IntegerField("pevná částka 1", default=100)
        form_amount_2 = models.IntegerField("pevná částka 2", default=200)
        form_amount_3 = models.IntegerField("pevná částka 3", default=500)
        form_amount_4 = models.IntegerField("pevná částka 4", default=1000)
        form_preselected = models.IntegerField(
            "výchozí částka", default=FIRST, choices=FORM_CHOICES
        )
    
        form_monthly_amount_1 = models.IntegerField("měsíční částka 1", default=100)
        form_monthly_amount_2 = models.IntegerField("měsíční částka 2", default=200)
        form_monthly_amount_3 = models.IntegerField("měsíční částka 3", default=500)
        form_monthly_amount_4 = models.IntegerField("měsíční částka 4", default=1000)
        form_monthly_preselected = models.IntegerField(
            "výchozí měsíční částka", default=FIRST, choices=FORM_CHOICES
        )
    
        class Meta:
            abstract = True
    
    
    class DonateHomePage(
        DonateFormMixin,
        DonateFormAmountsMixin,
        Page,
        ExtendedMetadataHomePageMixin,
        MetadataPageMixin,
    ):
        ### FIELDS
    
        # menu
        menu = StreamField(
            [
                ("menu_item", MenuItemBlock()),
                (
                    "menu_parent",
                    MenuParentBlock(),
                ),
            ],  # , ("menu_parent", MenuParentBlock())
            verbose_name="Menu",
            blank=True,
            use_json_field=True,
        )
    
        # lead section
        lead_title = models.CharField("hlavní nadpis", max_length=250, blank=True)
        lead_body = RichTextField("hlavní popis", blank=True)
        lead_video = models.URLField("video na youtube", blank=True, null=True)
        lead_preview = models.ForeignKey(
            "wagtailimages.Image",
            on_delete=models.PROTECT,
            blank=True,
            null=True,
            verbose_name="náhled videa",
        )
    
        # main section
        content_blocks = StreamField(
            [
                ("project_index", ProjectIndexBlock()),
                ("district_donation", DistrictDonationBlock()),
                ("party_support_form", PartySupportFormBlock()),
                ("custom", CustomContentBlock()),
            ],
            blank=True,
            use_json_field=True,
            verbose_name="Obsah",
        )
    
        # footer
        transparency_footer_items = StreamField(
            [("transparency_url", CustomLinkBlock(label="Odkaz"))],
            blank=True,
            use_json_field=True,
            verbose_name="Odkazy v patičkové sekci Otevřenost",
        )
    
        # settings
        faq_page = models.ForeignKey(
            "donate.DonateTextPage",
            on_delete=models.PROTECT,
            blank=True,
            null=True,
            related_name="FAQ",
            verbose_name="Stránka s FAQ",
        )
    
        custom_links = StreamField(
            [("custom_link", CustomLinkBlock(label="Vlastní odkaz"))],
            verbose_name="Vlastní odkazy",
            blank=True,
            use_json_field=True,
        )
    
        facebook = models.URLField("Facebook URL", blank=True, null=True)
        instagram = models.URLField("Instagram URL", blank=True, null=True)
        twitter = models.URLField("Twitter URL", blank=True, null=True)
        flickr = models.URLField("Flickr URL", blank=True, null=True)
        matomo_id = models.IntegerField(
            "Matomo ID pro sledování návštěvnosti", blank=True, null=True
        )
    
        ### PANELS
    
        content_panels = Page.content_panels + [
            MultiFieldPanel(
                [
                    FieldPanel("lead_title"),
                    FieldPanel("lead_body"),
                    FieldPanel("lead_video"),
                    FieldPanel("lead_preview"),
                ],
                "hlavní sekce",
            ),
            FieldPanel("content_blocks"),
            FieldPanel("transparency_footer_items"),
        ]
    
        menu_panels = [
            MultiFieldPanel(
                [
                    FieldPanel("menu"),
                ],
                heading="Nastavení menu",
            ),
        ]
    
        promote_panels = make_promote_panels(admin_help.build(admin_help.IMPORTANT_TITLE))
    
        settings_panels = [
            MultiFieldPanel(
                [FieldPanel("custom_links")],
                "vlastní odkazy",
            ),
            MultiFieldPanel(
                [
                    FieldPanel("facebook"),
                    FieldPanel("instagram"),
                    FieldPanel("twitter"),
                    FieldPanel("flickr"),
                ],
                "sociální sítě",
            ),
            FieldPanel("matomo_id"),
            FieldPanel("title_suffix"),
            MultiFieldPanel(
                [
                    FieldPanel("portal_project_id"),
                    FieldPanel("form_amount_1"),
                    FieldPanel("form_amount_2"),
                    FieldPanel("form_amount_3"),
                    FieldPanel("form_amount_4"),
                    FieldPanel("form_preselected"),
                    FieldPanel("form_monthly_amount_1"),
                    FieldPanel("form_monthly_amount_2"),
                    FieldPanel("form_monthly_amount_3"),
                    FieldPanel("form_monthly_amount_4"),
                    FieldPanel("form_monthly_preselected"),
                ],
                "nastavení darů",
            ),
            FieldPanel("faq_page"),
        ]
    
        ### EDIT HANDLERS
    
        edit_handler = TabbedInterface(
            [
                ObjectList(content_panels, heading="Obsah"),
                ObjectList(promote_panels, heading="Metadata"),
                ObjectList(settings_panels, heading="Nastavení"),
                ObjectList(menu_panels, heading="Menu"),
            ]
        )
    
        ### RELATIONS
    
        subpage_types = [
            "donate.DonateRegionIndexPage",
            "donate.DonateProjectIndexPage",
            "donate.DonateInfoPage",
            "donate.DonateTextPage",
        ]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = True
    
        class Meta:
            verbose_name = "Dary"
    
        @property
        def root_page(self):
            return self
    
        def get_404_response(self, request):
            return HttpResponseRedirect(self.full_url)
    
        @cached_property
        def info_page_url(self):
            return get_subpage_url(self, DonateInfoPage)
    
        @cached_property
        def project_indexes(self):
            return DonateProjectIndexPage.objects.child_of(self).live()
    
        @cached_property
        def regions_page_url(self):
            return get_subpage_url(self, DonateRegionIndexPage)
    
        @cached_property
        def has_projects(self):
            return self.get_descendants().type(DonateProjectPage).live().exists()
    
        def get_context(self, request):
            context = super().get_context(request)
    
            context["regions"] = (
                self.get_descendants().type(DonateRegionPage).live().specific()
            )
    
            return context
    
    
    class DonateRegionIndexPage(
        Page, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin
    ):
        ### PANELS
    
        promote_panels = make_promote_panels()
    
        settings_panels = []
    
        ### RELATIONS
    
        parent_page_types = ["donate.DonateHomePage"]
        subpage_types = ["donate.DonateRegionPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Přehled krajů"
    
        def get_context(self, request):
            context = super().get_context(request)
            context["regions"] = self.get_children().live().specific()
            return context
    
    
    class DonateRegionPage(
        DonateFormMixin,
        DonateFormAmountsMixin,
        Page,
        ExtendedMetadataPageMixin,
        SubpageMixin,
        MetadataPageMixin,
    ):
        ### FIELDS
    
        main_title = models.CharField("hlavní nadpis na stránce", max_length=250)
        body = RichTextField("obsah")
    
        ### PANELS
    
        content_panels = Page.content_panels + [
            FieldPanel("main_title"),
            FieldPanel("body"),
        ]
    
        promote_panels = make_promote_panels(
            admin_help.build(
                "Pokud není zadán <strong>Titulek stránky</strong>, použije "
                "se <strong>Hlavní nadpis</strong> (tab obsah).",
                admin_help.NO_SEARCH_IMAGE,
            )
        )
    
        settings_panels = [
            MultiFieldPanel(
                [
                    FieldPanel("portal_project_id"),
                    FieldPanel("form_amount_1"),
                    FieldPanel("form_amount_2"),
                    FieldPanel("form_amount_3"),
                    FieldPanel("form_amount_4"),
                    FieldPanel("form_preselected"),
                    FieldPanel("form_monthly_amount_1"),
                    FieldPanel("form_monthly_amount_2"),
                    FieldPanel("form_monthly_amount_3"),
                    FieldPanel("form_monthly_amount_4"),
                    FieldPanel("form_monthly_preselected"),
                ],
                "nastavení darů",
            ),
        ]
    
        ### RELATIONS
    
        parent_page_types = ["donate.DonateRegionIndexPage"]
        subpage_types = ["donate.DonateTargetedDonationsPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Kraj"
    
        @cached_property
        def targeted_donations_page_url(self):
            return get_subpage_url(self, DonateTargetedDonationsPage)
    
        @cached_property
        def has_targeted_donations(self):
            return self.get_descendants().type(DonateTargetedDonationsPage).live().exists()
    
    
    class DonateProjectIndexPage(
        Page, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin
    ):
        ### FIELDS
    
        heading = models.CharField("Hlavní nadpis", max_length=32)
    
        support_heading = models.CharField("Podpoř projekt nadpis", max_length=32)
        support_description = RichTextField("Podpoř projekt popis")
    
        ### PANELS
    
        content_panels = Page.content_panels + [
            FieldPanel("heading"),
            MultiFieldPanel(
                [
                    FieldPanel("support_heading"),
                    FieldPanel("support_description"),
                ],
                "Informace v sekci 'podpoř projekt' na homepage",
            ),
        ]
    
        promote_panels = make_promote_panels()
    
        settings_panels = []
    
        ### RELATIONS
    
        parent_page_types = ["donate.DonateHomePage"]
        subpage_types = ["donate.DonateProjectPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        @property
        def projects(self):
            return (
                DonateProjectPage.objects.child_of(self)
                .filter()
                .distinct()
                .order_by("-is_sticky", "-date")
                .live()
            )[:3]
    
        class Meta:
            verbose_name = "Přehled projektů"
    
        def get_context(self, request):
            context = super().get_context(request)
    
            paginator = Paginator(
                self.get_children().live().specific().order_by("-donateprojectpage__date"),
                6,
            )
    
            page = request.GET.get("page")
            try:
                projects = paginator.page(page)
            except PageNotAnInteger:
                projects = paginator.page(1)
            except EmptyPage:
                projects = paginator.page(paginator.num_pages)
    
            context["projects"] = projects
            return context
    
    
    class DonateProjectPage(
        DonateFormMixin,
        DonateFormAmountsMixin,
        Page,
        ExtendedMetadataPageMixin,
        SubpageMixin,
        MetadataPageMixin,
    ):
        TITLE_PROJECT = "Daruj na projekt"
    
        ### FIELDS
    
        date = models.DateField("Běží od")
        until = models.DateField("Běží do", null=True, blank=True)
    
        perex = models.TextField("Krátký popis")
        body = RichTextField("Obsah")
    
        is_new = models.BooleanField('Označení "nový projekt"', default=False)
        is_sticky = models.BooleanField(
            "Je připnutý",
            help_text="Pokud je projekt připnutý, na domovské stránce se v seznamech projektů udrží na začátku.",
            default=False,
        )
    
        allow_periodic_donations = models.BooleanField(
            "Umožnit pravidelné dary", default=False
        )
        photo = models.ForeignKey(
            "wagtailimages.Image",
            verbose_name="Fotka",
            on_delete=models.PROTECT,
            null=True,
            blank=True,
        )
        gallery = StreamField(
            [("photo", ImageChooserBlock(label="fotka"))],
            verbose_name="galerie fotek",
            blank=True,
            use_json_field=True,
        )
        form_title = models.CharField(
            "Titulek formuláře",
            help_text="Např. 'Daruj na projekt', 'Daruj na kampaň', ...",
            max_length=32,
            default=TITLE_PROJECT,
        )
        expected_amount = models.IntegerField("Očekávaná částka", blank=True, null=True)
        donated_amount = models.IntegerField("Vybraná částka", blank=True, null=True)
        coalition_design = models.BooleanField("Koaliční design", default=False)
        # we will use photo as search image
        search_image = None
    
        crowdfunding = StreamField(
            [("reward_block", CrowdfundingRewardBlock())],
            verbose_name="Crowdfunding bloky",
            blank=True,
            use_json_field=True,
        )
    
        ### PANELS
    
        content_panels = Page.content_panels + [
            MultiFieldPanel(
                [
                    FieldPanel("is_new"),
                    FieldPanel("is_sticky"),
                    FieldPanel("perex"),
                    FieldPanel("photo"),
                ],
                "Info do přehledu projektů",
            ),
            MultiFieldPanel(
                [
                    FieldPanel("date"),
                    FieldPanel("until"),
                ],
                "Časový interval projektu",
            ),
            FieldPanel("body"),
            FieldPanel("gallery"),
        ]
    
        promote_panels = make_promote_panels(
            admin_help.build(
                "Pokud není zadán <strong>Titulek stránky</strong>, použije "
                "se „Podpoř projekt <strong>Název</strong>“ (tab obsah).",
                admin_help.NO_DESCRIPTION_USE_PEREX,
            ),
            search_image=False,
        )
    
        settings_panels = [
            PublishingPanel(),
            MultiFieldPanel(
                [
                    FieldPanel("form_title"),
                    FieldPanel("expected_amount"),
                    FieldPanel("portal_project_id"),
                    FieldPanel("allow_periodic_donations"),
                    FieldPanel("form_amount_1"),
                    FieldPanel("form_amount_2"),
                    FieldPanel("form_amount_3"),
                    FieldPanel("form_amount_4"),
                    FieldPanel("form_preselected"),
                    FieldPanel("form_monthly_amount_1"),
                    FieldPanel("form_monthly_amount_2"),
                    FieldPanel("form_monthly_amount_3"),
                    FieldPanel("form_monthly_amount_4"),
                    FieldPanel("form_monthly_preselected"),
                ],
                "nastavení darů",
            ),
            MultiFieldPanel(
                [
                    FieldPanel("crowdfunding"),
                ],
                "Nastavení crowdfundingových odměn",
            ),
            FieldPanel("coalition_design"),
        ]
    
        ### RELATIONS
    
        parent_page_types = ["donate.DonateProjectIndexPage"]
        subpage_types = ["donate.DonateSecretPreviewPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Projekt"
    
        def get_meta_image(self):
            return self.photo
    
        def get_meta_description(self):
            if self.search_description:
                return self.search_description
            if len(self.perex) > 150:
                return str(self.perex)[:150] + "..."
            return self.perex
    
        def get_donated_amount(self):
            if self.portal_project_id is None:
                return 0
            # instance caching for multiple method calls during one request
            if not hasattr(self, "_donated_amount"):
                # cache portal API calls (defaults to 5 min)
                key = f"donated_amount_{self.portal_project_id}"
                amount = cache.get(key)
                if amount is None:
                    amount = get_donated_amount_from_api(self.portal_project_id)
                    if amount is not None:
                        # save amount into database to be used if next API calls fails
                        self.donated_amount = amount
                        self.save()
                        cache.set(key, amount, settings.DONATE_PORTAL_API_CACHE_TIMEOUT)
                self._donated_amount = self.donated_amount or 0
            return self._donated_amount
    
        @property
        def donated_percentage(self):
            if not self.expected_amount:
                return 0
            if self.get_donated_amount() >= self.expected_amount:
                return 100
            return round(self.get_donated_amount() / self.expected_amount * 100)
    
        def get_context(self, request):
            context = super().get_context(request)
            context["other_projects"] = (
                self.get_siblings(inclusive=False)
                .live()
                .specific()
                .order_by("-donateprojectpage__date")[:3]
            )
            return context
    
        def get_template(self, request, *args, **kwargs):
            if self.coalition_design:
                return "donate/donate_project_page_coalition.html"
            return super().get_template(request, *args, **kwargs)
    
    
    class DonateTextPage(Page, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin):
        ### FIELDS
    
        body = RichTextField("obsah", blank=True)
    
        ### PANELS
    
        content_panels = Page.content_panels + [FieldPanel("body")]
    
        promote_panels = make_promote_panels()
    
        settings_panels = []
    
        ### RELATIONS
    
        parent_page_types = [
            "donate.DonateHomePage",
            "donate.DonateTextPage",
            "donate.DonateInfoPage",
        ]
        subpage_types = ["donate.DonateTextPage", "donate.DonateInfoPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Stránka s textem"
    
    
    class DonateInfoPage(
        DonateFormMixin,
        DonateFormAmountsMixin,
        Page,
        ExtendedMetadataPageMixin,
        SubpageMixin,
        MetadataPageMixin,
    ):
        ### FIELDS
    
        body = RichTextField("obsah", blank=True)
    
        ### PANELS
    
        content_panels = Page.content_panels + [FieldPanel("body")]
    
        promote_panels = make_promote_panels()
    
        settings_panels = [
            PublishingPanel(),
            MultiFieldPanel(
                [
                    FieldPanel("form_amount_1"),
                    FieldPanel("form_amount_2"),
                    FieldPanel("form_amount_3"),
                    FieldPanel("form_amount_4"),
                    FieldPanel("form_preselected"),
                    FieldPanel("form_monthly_amount_1"),
                    FieldPanel("form_monthly_amount_2"),
                    FieldPanel("form_monthly_amount_3"),
                    FieldPanel("form_monthly_amount_4"),
                    FieldPanel("form_monthly_preselected"),
                ],
                "nastavení darů",
            ),
        ]
    
        ### RELATIONS
    
        parent_page_types = [
            "donate.DonateHomePage",
            "donate.DonateTextPage",
            "donate.DonateInfoPage",
        ]
        subpage_types = ["donate.DonateTextPage", "donate.DonateInfoPage"]
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Infostránka s formulářem"
    
        # use portal_project_id from home page
        @cached_property
        def portal_project_id(self):
            return self.get_parent().specific.portal_project_id
    
    
    class TargetedDonation(Orderable):
        page = ParentalKey(
            "donate.DonateTargetedDonationsPage",
            on_delete=models.CASCADE,
            related_name="targeted_donations",
        )
        is_main = models.BooleanField(
            "hlavní dar", default=False, help_text="zobrazené samostatně nahoře"
        )
        title = models.CharField("název", max_length=255)
        description = models.CharField(
            "popis",
            null=True,
            blank=True,
            max_length=255,
            help_text="zobrazí se jen u hlavních darů",
        )
        portal_project_id = models.IntegerField("ID projektu v darovacím portálu")
    
        panels = [
            FieldPanel("portal_project_id"),
            FieldPanel("title"),
            FieldPanel("description"),
            FieldPanel("is_main"),
        ]
    
    
    class DonateTargetedDonationsPage(
        DonateFormMixin,
        DonateFormAmountsMixin,
        Page,
        ExtendedMetadataPageMixin,
        SubpageMixin,
        MetadataPageMixin,
    ):
        ### FIELDS
    
        # page does not have specific portal_project_id
        portal_project_id = None
    
        ### PANELS
    
        content_panels = Page.content_panels + [
            MultiFieldPanel([InlinePanel("targeted_donations")], "adresné dary"),
        ]
    
        promote_panels = make_promote_panels()
    
        settings_panels = [
            PublishingPanel(),
            MultiFieldPanel(
                [
                    FieldPanel("form_amount_1"),
                    FieldPanel("form_amount_2"),
                    FieldPanel("form_amount_3"),
                    FieldPanel("form_amount_4"),
                    FieldPanel("form_preselected"),
                    FieldPanel("form_monthly_amount_1"),
                    FieldPanel("form_monthly_amount_2"),
                    FieldPanel("form_monthly_amount_3"),
                    FieldPanel("form_monthly_amount_4"),
                    FieldPanel("form_monthly_preselected"),
                ],
                "nastavení darů",
            ),
        ]
    
        ### RELATIONS
    
        parent_page_types = ["donate.DonateRegionPage"]
        subpage_types = []
    
        ### OTHERS
    
        # flag for rendering anchor links in menu
        is_home = False
    
        class Meta:
            verbose_name = "Adresné dary"
    
        def get_context(self, request):
            context = super().get_context(request)
    
            try:
                selected_project_id = int(request.GET.get("p", 0))
                selected_target = self.targeted_donations.get(
                    portal_project_id=selected_project_id
                )
            except (ValueError, TargetedDonation.DoesNotExist):
                selected_target = None
    
            if selected_target:
                context["main_targets"] = [selected_target]
                context["other_targets"] = []
                context["is_preselected"] = True
            else:
                context["main_targets"] = self.targeted_donations.filter(is_main=True)
                context["other_targets"] = self.targeted_donations.filter(is_main=False)
                context["is_preselected"] = False
    
            if context["main_targets"]:
                context["initial_project_id"] = context["main_targets"][0].portal_project_id
            elif context["other_targets"]:
                context["initial_project_id"] = context["other_targets"][
                    0
                ].portal_project_id
            else:
                context["initial_project_id"] = 0
    
            return context
    
    
    class DonateSecretPreviewPage(Page):
        max_count_per_parent = 1
    
        parent_page_types = [
            "donate.DonateProjectPage",
        ]
        subpage_types = []
    
        class Meta:
            verbose_name = "Skrytá stránka pro náhled konceptu"
    
        def get_context(self, request, *args, **kwargs):
            parent_page = self.get_parent().get_latest_revision_as_object()
            context = parent_page.get_context(request=request)
    
            context.update({"disable_robots": True})
    
            return context
    
        def get_template(self, request, *args, **kwargs):
            parent_page = self.get_parent().get_latest_revision_as_object()
            return parent_page.get_template(request, *args, **kwargs)
    
        def serve(self, request, *args, **kwargs):
            return TemplateResponse(
                request,
                self.get_template(request, *args, **kwargs),
                self.get_context(request, *args, **kwargs),
            )