无法使用 get_context 获取博客列表以正常工作

Cannot get blog listing using get_context to work properly

我正在尝试使用 wagtail 2.13 创建一个博客列表页面,但只设法让 {{ post.date }} {{ post.url }} 部分正常工作。

{{ post.heading }}{{ post.standfirst }} 没有出现。我尝试了一些排列,例如 {{ post.heading }} {{ post.content.heading }} {{ post.block.heading }} 但它们没有用。

此处使用的正确 {{ }} 查询是什么?

Image of partially working listing

#models.py

from django.db import models

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

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 = "home/home_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')
        return context

class BlogPage(Page):
    """ For individual blog pages."""

    author = models.CharField(max_length=255, default="Niq")
    date = models.DateField("Post date")
    content = StreamField([
        ('heading', blocks.CharBlock(form_classname="full title")),
        ('standfirst', blocks.CharBlock()),
        ('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'),
        StreamFieldPanel('content'),
    ]

    template = "blog/blog_page.html"

#home_page.html

{% extends 'base.html' %}

{% block content %}

    <div class="container">
        {% for post in posts %}
            <div class="row mt-5 mb-5">
                <div class="col-sm-9">
                    <a href="{{ post.url }}">
                    test test
                        <h2>{{ post.heading }}</h2>
                        <h2>{{ post.standfirst }}</h2>
                        <h2>{{ post.date }}</h2>
                        <a href="{{ post.url }}" class="btn btn-primary mt-4">Read More</a>
                    </a>
                </div>
            </div>
        {% empty %}
        <h2>No posts</h2>
        {% endfor %}
    </div>

{% endblock content %}

StreamField 中的项目表现为列表 - 您不能通过名称访问它们,只能通过它们的位置。一般来说,像 post.content.heading 这样的东西是行不通的,因为 StreamField 可能有多个标题项,或者根本没有 none。 (在这种情况下,您的 block_counts 定义阻止了这种情况,但这不会改变访问元素的方式。)

作为解决此问题的方法,您可以在 BlogPage 上定义 heading 方法或 属性,它循环遍历 StreamField 值以找到适当类型的块:

class BlogPage(Page):
    # ...

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

然后您将能够使用 {{ post.heading }} 从模板访问此 属性。