You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
datasketch-io/services/cms/blog/models.py

80 lines
3.1 KiB
Python

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.core.models import Page, Orderable
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.search import index
class BlogIndexPage(Page):
"""Entry point of the blog. Displays its children `BlogPages`"""
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [FieldPanel("intro", classname="full")]
def get_context(self, request, *args, **kwargs):
"""
Overrides the default context to include only published pages, ordered by reverse chronological order.
These child pages can be accessed in the template using `blogpages` instead of page.get_children.
"""
context = super().get_context(request)
blogpages = self.get_children().live().order_by("-first_published_at")
context["blogpages"] = blogpages
return context
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
def main_image(self):
"""Returns the first image associated with a `BlogPage` from `BlogPageGalleryImage`"""
gallery_item = self.gallery_images.first()
if gallery_item:
return gallery_item.image
else:
return None
search_fields = Page.search_fields + [
index.SearchField("intro"),
index.SearchField("body"),
]
content_panels = Page.content_panels + [
FieldPanel("date"),
FieldPanel("intro"),
FieldPanel("body", classname="full"),
InlinePanel("gallery_images", label="Gallery images"),
]
class BlogPageGalleryImage(Orderable):
"""
An image gallery descendant to a `BlogPage`
Inherits a `sort_order` field from the `Orderable` object which keeps track of image ordering.
The `ParentalKey` works similarly to a `ForeignKey` but also defines this class as a child of `BlogPage` model.
This means that the image gallery associated with a particular `BlogPage` instance is treated as a part of the page
in operations like submitting for moderation, and tracking version history.
The `BlogPageGalleryImage.image` is a `ForeignKey to the Wagtail built-in `Image` model where images themselves are
stored. The `ImageChooserPanel` provides a popup interface for choosing an existing image or uploading a new one.
This allows for the same image to exist in multiple galleries - effectively creating a many-to-many relationship
between pages and images.
"""
page = ParentalKey(
BlogPage, on_delete=models.CASCADE, related_name="gallery_images"
)
image = models.ForeignKey(
# on_delete here means that is an image is deleted from the system, the gallery entry is deleted as well.
"wagtailimages.Image", on_delete=models.CASCADE, related_name="+"
)
caption = models.CharField(blank=True, max_length=250)
panels = [ImageChooserPanel("image"), FieldPanel("caption")]