在 base.html 侧边栏中获取和显示最新帖子

Getting and showing latest posts in base.html sidebar

我正试图在 base.html 的侧边栏中显示 3 个最新帖子。我发现了一个以前的问题 () 并尝试关注,但帖子没有出现。

如有任何关于如何继续的提示,我们将不胜感激。谢谢!

# blog/models.py
from django.db import models

from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from wagtail.core.models import Page
from wagtail.core.fields import StreamField
from wagtail.core import blocks
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.images.blocks import ImageChooserBlock
from wagtail.snippets.models import register_snippet

richtext_features = [
    'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 
    "ol", "ul", "hr", 
    "link", "document-link", 
    "image", "embed",
    "code", "blockquote",
    "superscript", "subscript", "strikethrough",
]


class BlogListingPage(Page):
    """Listing page lists all the Blog pages."""

    template = "blog/blog_listing_page.html"

    custom_title = models.CharField(
        max_length=255,
        blank=False,
        null=False,
        help_text='Overwrites the default title',
    )

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
    ]

    def get_context(self, request, *args, **kwargs):
        """Adding custom stuff to our context."""
        context = super().get_context(request, *args, **kwargs)
        context["posts"] = BlogPage.objects.live().public().order_by('-date')
        context["latest_posts"] = context["posts"][:3]

        if request.GET.get('tag', None):
            tags = request.GET.get('tag')
            all_posts = context["posts"].filter(tags__slug__in=[tags])

        return context

    class Meta:

        verbose_name = "Blog Listing Page"
        verbose_name_plural = "Blog Listing Pages"


@register_snippet
class BlogTag(TaggedItemBase):
    content_object = ParentalKey(
        'BlogPage',
        on_delete=models.CASCADE,
    )
    
    class Meta:
        verbose_name = "Blog Tag"
        verbose_name_plural = "Blog Tags"


class BlogPage(Page):
    """ For individual blog pages."""
        
    template = "blog/blog_page.html"
    parent_page_types = ['blog.BlogListingPage']
    tags = ClusterTaggableManager(through=BlogTag, blank=True)

    author = models.CharField(max_length=255, default="Niq")
    date = models.DateField("Post date")
    content = StreamField([
        ('heading', blocks.CharBlock(form_classname="full title")),
        ('standfirst', blocks.RichTextBlock(features=richtext_features)),
        ('paragraph', blocks.RichTextBlock(features=richtext_features)),
        ('image', ImageChooserBlock()),
    ], block_counts={
        'heading': {'min_num': 1, 'max_num': 1,},
        'standfirst': {'max_num': 1,},
    })

    content_panels = Page.content_panels + [
        FieldPanel('author'),
        FieldPanel('date'),
        FieldPanel("tags"),
        StreamFieldPanel('content'),
    ]

    @property
    def heading(self):
        for block in self.content:
            if block.block_type == 'heading':
                return block.value

    @property
    def standfirst(self):
        for block in self.content:
            if block.block_type == 'standfirst':
                return block.value


    class Meta:

        verbose_name = "Blog Page"
        verbose_name_plural = "Blog Pages"

blog/templatetags/show_latest_posts.py

from django import template
register = template.Library()

from ..models import BlogPage

@register.inclusion_tag('blog/show_latest_posts.html')
def show_latest_posts():
    latest_posts = BlogPage.objects.live().public().order_by('-date')[:3]
    return {'latest_posts': latest_posts}
    # return latest_posts

templates/blog/show_latest_posts.html

<b>Latest Posts</b>
{% for post in latest_posts %}
  <br><a href="{{ post.url }}" class="text-body text-decoration-none">{{ post.heading }}</a>
{% endfor %}

base.html的一部分

<div class="right">
    {% load show_latest_posts %}
    {% show_latest_posts %}
</div>

{% for post in page.latest_posts %}

应该是

{% for post in latest_posts %}

在这里,page.latest_posts 将引用当前页面对象上的 latest_posts 方法,但您没有以这种方式定义它 - 相反,您在 get_context 方法,它使模板内的结果作为变量 latest_posts(不是 page.latest_posts)可用。

请记住,latest_posts 变量仅适用于您在 get_context 方法中定义该变量的页面类型。在这种情况下,您会发现最新的帖子列表显示在 BlogIndexPage 上,而不是 BlogPage。您可以在 BlogPage 的 get_context 方法中重复相同的代码,但更好的方法可能是使用自定义 inclusion template tag 来检索和显示列表 - 这样,代码是完全独立的并且不需要在页面模型中进行任何额外的查询。