website/website/blog/models.py

128 lines
3.7 KiB
Python
Raw Normal View History

from typing import Any, Optional, Type
2022-06-19 19:24:29 +01:00
2022-06-19 20:55:37 +01:00
from django.db import models
2022-06-19 21:03:05 +01:00
from django.utils import timezone
from django.utils.functional import cached_property
from modelcluster.fields import ParentalManyToManyField
2022-06-19 20:55:37 +01:00
from wagtail.admin.panels import FieldPanel
2022-08-28 16:18:31 +01:00
from wagtailautocomplete.edit_handlers import AutocompletePanel
2022-06-19 19:24:29 +01:00
from website.common.models import BaseContentPage, BaseListingPage
from website.common.utils import TocEntry
from website.common.views import ContentPageFeed
from website.contrib.singleton_page.utils import SingletonPageCache
2022-06-19 19:24:29 +01:00
class BlogPostListPage(BaseListingPage):
2022-06-19 19:24:29 +01:00
max_count = 1
subpage_types = [
"blog.BlogPostPage",
"blog.BlogPostTagListPage",
"blog.BlogPostCollectionListPage",
"blog.BlogPostCollectionPage",
]
2022-06-19 19:24:29 +01:00
@cached_property
def table_of_contents(self) -> list[TocEntry]:
"""
Showing an accurate ToC is complex alongside pagination
"""
return []
def get_listing_pages(self) -> models.QuerySet:
return (
2022-08-28 16:18:31 +01:00
BlogPostPage.objects.descendant_of(self)
.live()
2022-08-28 16:51:27 +01:00
.public()
2022-08-28 16:18:31 +01:00
.order_by("-date", "title")
2022-06-19 19:24:29 +01:00
)
@property
def feed_class(self) -> Type[ContentPageFeed]:
2022-07-25 21:58:06 +01:00
from .views import BlogPostPageFeed
return BlogPostPageFeed
2022-07-25 21:58:06 +01:00
2022-06-19 19:24:29 +01:00
class BlogPostPage(BaseContentPage):
2022-06-19 19:24:29 +01:00
subpage_types: list[Any] = []
parent_page_types = [BlogPostListPage, "blog.BlogPostCollectionPage"]
2022-06-19 20:55:37 +01:00
tags = ParentalManyToManyField("blog.BlogPostTagPage", blank=True)
2022-06-19 21:03:05 +01:00
date = models.DateField(default=timezone.now)
2022-06-19 20:55:37 +01:00
promote_panels = BaseContentPage.promote_panels + [
FieldPanel("date"),
2022-08-28 16:18:31 +01:00
AutocompletePanel("tags"),
]
@cached_property
def tag_list_page_url(self) -> Optional[str]:
return SingletonPageCache.get_url(BlogPostTagListPage)
class BlogPostTagListPage(BaseListingPage):
max_count = 1
parent_page_types = [BlogPostListPage]
subpage_types = ["blog.BlogPostTagPage"]
@cached_property
def table_of_contents(self) -> list[TocEntry]:
return [
TocEntry(page.title, page.slug, 0, []) for page in self.get_listing_pages()
]
class BlogPostTagPage(BaseListingPage):
subpage_types: list[Any] = []
parent_page_types = [BlogPostTagListPage]
2022-08-27 13:12:45 +01:00
@cached_property
def html_title(self) -> str:
return f"Pages tagged with '{super().html_title}'"
def get_listing_pages(self) -> models.QuerySet:
2022-08-28 16:51:27 +01:00
blog_list_page = BlogPostListPage.objects.get()
return blog_list_page.get_listing_pages().filter(tags=self)
@property
def feed_class(self) -> Type[ContentPageFeed]:
2022-07-25 21:58:06 +01:00
from .views import BlogPostPageFeed
return BlogPostPageFeed
2022-07-25 21:58:06 +01:00
class BlogPostCollectionListPage(BaseListingPage):
subpage_types: list[Any] = []
parent_page_types = [BlogPostListPage]
max_count = 1
@cached_property
def table_of_contents(self) -> list[TocEntry]:
return [
TocEntry(page.title, page.slug, 0, []) for page in self.get_listing_pages()
]
def get_listing_pages(self) -> models.QuerySet:
2022-08-28 20:22:55 +01:00
blog_list_page = BlogPostListPage.objects.get()
2022-08-28 16:51:27 +01:00
return BlogPostCollectionPage.objects.child_of(blog_list_page).live().public()
class BlogPostCollectionPage(BaseListingPage):
parent_page_types = [BlogPostListPage]
subpage_types = [BlogPostPage]
def get_listing_pages(self) -> models.QuerySet:
return (
2022-08-28 16:18:31 +01:00
BlogPostPage.objects.child_of(self)
.live()
2022-08-28 16:51:27 +01:00
.public()
.order_by("-date", "title")
)
@property
def feed_class(self) -> Type[ContentPageFeed]:
from .views import BlogPostPageFeed
return BlogPostPageFeed