Add method to prefetch for listing
This commit is contained in:
parent
735ab73ec0
commit
c660e54bae
4 changed files with 29 additions and 23 deletions
|
@ -8,7 +8,7 @@ from modelcluster.fields import ParentalManyToManyField
|
||||||
from wagtail.admin.panels import FieldPanel
|
from wagtail.admin.panels import FieldPanel
|
||||||
|
|
||||||
from website.common.models import BaseContentPage, BaseListingPage
|
from website.common.models import BaseContentPage, BaseListingPage
|
||||||
from website.common.utils import TocEntry
|
from website.common.utils import TocEntry, prefetch_for_listing
|
||||||
from website.common.views import ContentPageFeed
|
from website.common.views import ContentPageFeed
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,12 +37,8 @@ class BlogPostListPage(BaseListingPage):
|
||||||
return [TocEntry(post_month, post_month, 0, []) for post_month in post_months]
|
return [TocEntry(post_month, post_month, 0, []) for post_month in post_months]
|
||||||
|
|
||||||
def get_listing_pages(self) -> models.QuerySet:
|
def get_listing_pages(self) -> models.QuerySet:
|
||||||
return (
|
return prefetch_for_listing(
|
||||||
BlogPostPage.objects.descendant_of(self)
|
BlogPostPage.objects.descendant_of(self).live().order_by("-date", "title").prefetch_related("tags")
|
||||||
.live()
|
|
||||||
.select_related("hero_image", "hero_unsplash_photo")
|
|
||||||
.prefetch_related("tags")
|
|
||||||
.order_by("-date", "title")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -117,9 +113,8 @@ class BlogPostCollectionPage(BaseListingPage):
|
||||||
subpage_types = [BlogPostPage]
|
subpage_types = [BlogPostPage]
|
||||||
|
|
||||||
def get_listing_pages(self) -> models.QuerySet:
|
def get_listing_pages(self) -> models.QuerySet:
|
||||||
return (
|
return prefetch_for_listing(
|
||||||
BlogPostPage.objects.child_of(self)
|
BlogPostPage.objects.child_of(self).live()
|
||||||
.select_related("hero_image", "hero_unsplash_photo")
|
|
||||||
.prefetch_related("tags")
|
.prefetch_related("tags")
|
||||||
.order_by("-date", "title")
|
.order_by("-date", "title")
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,12 +22,18 @@ from wagtail.search import index
|
||||||
from wagtail.snippets.models import register_snippet
|
from wagtail.snippets.models import register_snippet
|
||||||
from wagtailmetadata.models import MetadataMixin
|
from wagtailmetadata.models import MetadataMixin
|
||||||
|
|
||||||
from website.common.utils import count_words
|
|
||||||
from website.contrib.unsplash.widgets import UnsplashPhotoChooser
|
from website.contrib.unsplash.widgets import UnsplashPhotoChooser
|
||||||
|
|
||||||
from .serializers import PaginationSerializer
|
from .serializers import PaginationSerializer
|
||||||
from .streamfield import add_heading_anchors, get_blocks, get_content_html
|
from .streamfield import add_heading_anchors, get_blocks, get_content_html
|
||||||
from .utils import TocEntry, extract_text, get_table_of_contents, truncate_string
|
from .utils import (
|
||||||
|
TocEntry,
|
||||||
|
count_words,
|
||||||
|
extract_text,
|
||||||
|
get_table_of_contents,
|
||||||
|
prefetch_for_listing,
|
||||||
|
truncate_string,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BasePage(Page):
|
class BasePage(Page):
|
||||||
|
@ -196,12 +202,8 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage):
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
def get_listing_pages(self) -> models.QuerySet:
|
def get_listing_pages(self) -> models.QuerySet:
|
||||||
return (
|
return prefetch_for_listing(
|
||||||
self.get_children()
|
self.get_children().live().specific().order_by("title")
|
||||||
.live()
|
|
||||||
.specific()
|
|
||||||
.select_related("hero_image", "hero_unsplash_photo")
|
|
||||||
.order_by("title")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_paginator_page(self) -> PaginatorPage:
|
def get_paginator_page(self) -> PaginatorPage:
|
||||||
|
|
|
@ -9,6 +9,7 @@ from django.utils.text import slugify, smart_split
|
||||||
from more_itertools import ilen
|
from more_itertools import ilen
|
||||||
from wagtail.models import Page
|
from wagtail.models import Page
|
||||||
from wagtail.models import get_page_models as get_wagtail_page_models
|
from wagtail.models import get_page_models as get_wagtail_page_models
|
||||||
|
from wagtail.query import PageQuerySet
|
||||||
|
|
||||||
HEADER_TAGS = ["h2", "h3", "h4", "h5", "h6"]
|
HEADER_TAGS = ["h2", "h3", "h4", "h5", "h6"]
|
||||||
|
|
||||||
|
@ -84,3 +85,13 @@ def extract_text(html: str) -> str:
|
||||||
|
|
||||||
def truncate_string(text: str, words: int) -> str:
|
def truncate_string(text: str, words: int) -> str:
|
||||||
return " ".join(islice(smart_split(text), words))
|
return " ".join(islice(smart_split(text), words))
|
||||||
|
|
||||||
|
|
||||||
|
def prefetch_for_listing(queryset: PageQuerySet) -> PageQuerySet:
|
||||||
|
"""
|
||||||
|
Prefetch a queryset ready for listing.
|
||||||
|
|
||||||
|
This should be a queryset method, but dealing with lots of
|
||||||
|
different page models is a pain.
|
||||||
|
"""
|
||||||
|
return queryset.select_related("hero_image", "hero_unsplash_photo")
|
||||||
|
|
|
@ -10,7 +10,7 @@ from wagtail.models import Page
|
||||||
from wagtail.search.utils import parse_query_string
|
from wagtail.search.utils import parse_query_string
|
||||||
|
|
||||||
from website.common.models import BaseContentPage
|
from website.common.models import BaseContentPage
|
||||||
from website.common.utils import TocEntry
|
from website.common.utils import TocEntry, prefetch_for_listing
|
||||||
from website.home.models import HomePage
|
from website.home.models import HomePage
|
||||||
|
|
||||||
from .serializers import MIN_SEARCH_LENGTH, SearchParamsSerializer
|
from .serializers import MIN_SEARCH_LENGTH, SearchParamsSerializer
|
||||||
|
@ -75,10 +75,8 @@ class SearchPage(RoutablePageMixin, BaseContentPage):
|
||||||
results = paginator.page(page_num)
|
results = paginator.page(page_num)
|
||||||
|
|
||||||
# HACK: Search results aren't a queryset, so we can't call `.specific` on it. This forces it to one as efficiently as possible
|
# HACK: Search results aren't a queryset, so we can't call `.specific` on it. This forces it to one as efficiently as possible
|
||||||
results.object_list = (
|
results.object_list = prefetch_for_listing(
|
||||||
results.object_list.get_queryset()
|
results.object_list.get_queryset().specific()
|
||||||
.specific()
|
|
||||||
.select_related("hero_image", "hero_unsplash_photo")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
except EmptyPage:
|
except EmptyPage:
|
||||||
|
|
Loading…
Reference in a new issue