Source code for eucrim.core.models.pages

# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2

from django.db import models
from django.utils import timezone

from wagtail.search import index
from wagtail.models import Page, Orderable
from wagtail.fields import RichTextField, StreamField
from wagtail.admin.panels import (
    FieldPanel,
    InlinePanel,
    MultiFieldPanel,
    FieldRowPanel,
)

from modelcluster.fields import ParentalKey

from eucrim.article.models import (
    ArticlePage,
    ArticleIndexPage,
    article_authors_prefetch,
)
from eucrim.issue.models import IssuePage, IssueIndexPage
from eucrim.news.models import NewsPage, NewsIndexPage
from eucrim.event.models import EventPage, EventIndexPage

from ..blocks import BaseStreamBlock
from ..abstracts import CarouselItem


[docs] class HomePageCarouselItem(Orderable, CarouselItem): page = ParentalKey("core.HomePage", related_name="carousel_items")
[docs] class HomePage(Page): parent_page_types = ["wagtailcore.Page"] subpage_types = [ "StandardPage", "article.ArticleIndexPage", "association.AssociationIndexPage", "issue.IssueIndexPage", "news.NewsIndexPage", "event.EventIndexPage", "treaty.TreatyIndexPage", "profile.ProfileIndexPage", "procedure.ProcedureIndexPage", ] max_count = 1 # TODO: This today instanciation seems weird _today = timezone.now().date() about = RichTextField(blank=True) body = StreamField( BaseStreamBlock, verbose_name="Page body", blank=True, use_json_field=True, ) last_articles_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=5, help_text="Show X latest articles on homepage (default: 5)", ) last_editorials_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=1, help_text="Show X latest editorials on homepage (default: 1)", ) last_news_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=5, help_text="Show X latest news on homepage (default: 5). In addition, " "up to X featured news will be shown.", ) last_featured_news_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=3, help_text="Show X latest featured news on homepage (default: 3) on top " "of the standard news.", ) last_issues_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=5, help_text="Show X latest issues on homepage (default: 5)", ) last_events_quantity = models.PositiveSmallIntegerField( blank=True, null=True, default=5, help_text="Show X latest events on homepage (default: 5)", )
[docs] def get_event_index_page(self): return EventIndexPage.objects.live().first()
[docs] def get_news_index_page(self): return NewsIndexPage.objects.live().first()
[docs] def get_article_index_page(self): return ArticleIndexPage.objects.live().first()
[docs] def get_issue_index_page(self): return IssueIndexPage.objects.live().first()
[docs] def latest_articles(self): return ( ArticlePage.objects.live() .prefetch_related(article_authors_prefetch()) .exclude(article_type=ArticlePage.EDITORIAL) .order_by("-publication_date")[: self.last_articles_quantity] )
[docs] def latest_editorials(self): return ( ArticlePage.objects.live() .prefetch_related(article_authors_prefetch()) .filter(article_type=ArticlePage.EDITORIAL) .order_by("-publication_date")[: self.last_editorials_quantity] )
[docs] def latest_issues(self): return ( IssuePage.objects.live() .select_related("cover_image") .order_by("-year", "-issue_number")[: self.last_issues_quantity] )
[docs] def latest_news(self): return NewsPage.standardnews_objects.exclude(is_featured_news=True)[ : self.last_news_quantity ]
[docs] def latest_events(self): return ( EventPage.objects.live() .filter(event_date_from__gte=self._today) .order_by("event_date_from")[: self.last_events_quantity] )
search_fields = Page.search_fields + [ index.SearchField("about"), ] content_panels = Page.content_panels + [ FieldPanel("about", classname="full"), FieldPanel("body"), ] settings_panels = Page.settings_panels + [ FieldPanel("last_articles_quantity"), FieldPanel("last_editorials_quantity"), FieldPanel("last_news_quantity"), FieldPanel("last_featured_news_quantity"), FieldPanel("last_issues_quantity"), FieldPanel("last_events_quantity"), ]
[docs] class StandardPage(Page): intro = models.TextField(help_text="Text to describe the page", blank=True) body = StreamField( BaseStreamBlock, verbose_name="Page body", blank=True, use_json_field=True, ) content_panels = Page.content_panels + [ FieldPanel("intro", classname="full"), FieldPanel("body"), ] promote_panels = Page.promote_panels search_fields = Page.search_fields + [ index.SearchField("body"), ]
# The abstract model for abbreviations, complete with panels
[docs] class Abbreviation(index.Indexed, models.Model): term = models.CharField(max_length=255) abbreviation = models.CharField(max_length=255) panels = [ MultiFieldPanel( [ FieldRowPanel( [ FieldPanel("abbreviation"), FieldPanel("term"), ] ), ] ), ]
[docs] class Meta: abstract = True ordering = ["abbreviation"]
# The real model which combines the abstract model, an # Orderable helper class, and what amounts to a ForeignKey link # to the model we want to add abbreviations to (AbbreviationIndexPage)
[docs] class AbbreviationIndexPage(Page): body = RichTextField(blank=True) content_panels = Page.content_panels + [ FieldPanel("body"), InlinePanel("abbreviations", label="Abbreviations"), ] search_fields = Page.search_fields + [ index.SearchField("body"), ]