在 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 来检索和显示列表 - 这样,代码是完全独立的并且不需要在页面模型中进行任何额外的查询。
我正试图在 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 来检索和显示列表 - 这样,代码是完全独立的并且不需要在页面模型中进行任何额外的查询。