You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wagtail:如何在StructBlock模板访问Page对象及优化方案

解决方案

一、将Page对象传入Block模板的方法

你需要在自定义的ProgramEntryBlock中重写get_context方法,从父上下文(页面渲染时的上下文)中提取page对象并传递给Block模板:

from wagtail.core import blocks
from django.utils.translation import gettext_lazy as _

class ProgramEntryBlock(blocks.StructBlock):
    class Meta:
        label = _("Program entry")
        template = "blocks/program-entry-block.html"

    def get_context(self, value, parent_context=None):
        # 获取Block基础上下文
        context = super().get_context(value, parent_context=parent_context)
        # 从父上下文提取page对象并注入当前上下文
        if parent_context and 'page' in parent_context:
            context['page'] = parent_context['page']
        return context

修改后,blocks/program-entry-block.html模板就能直接使用page变量,访问关联的program_entries数据了。

二、更优的实现方案

由于你的ProgramEntryBlock不需要编辑者输入任何内容(仅用来展示已关联的节目单条目),用StructBlock存在冗余,更合适的做法是直接继承blocks.Block,简化Block定义:

class ProgramEntryBlock(blocks.Block):
    class Meta:
        label = _("Program entry")
        template = "blocks/program-entry-block.html"

    def get_context(self, value, parent_context=None):
        context = super().get_context(value, parent_context=parent_context)
        if parent_context and 'page' in parent_context:
            context['page'] = parent_context['page']
        return context

    # 无需存储值,返回空默认值
    def get_default(self):
        return None

    # 渲染空表单(因为不需要编辑内容)
    def render_form(self, value, prefix='', errors=None):
        return ''

同时确保ProgramEntry模型的关联逻辑正确:

from django.db import models
from wagtail.core.models import Page
from modelcluster.fields import ParentalKey

class ProgramEntry(models.Model):
    page = ParentalKey('your_app.Event', related_name='program_entries', on_delete=models.CASCADE)
    title = models.CharField(max_length=255, verbose_name="节目名称")
    start_time = models.TimeField(verbose_name="开始时间")
    description = models.TextField(verbose_name="节目描述", blank=True)

    class Meta:
        ordering = ['start_time']  # 按时间排序节目单

最后在Event页面模型的StreamField中添加该Block:

from wagtail.core.fields import StreamField
from wagtail.admin.panels import StreamFieldPanel

class Event(Page):
    body = StreamField([
        ('program', ProgramEntryBlock()),
        # 其他你需要的Block类型,比如文本、图片等
    ], use_json_field=True)

    content_panels = Page.content_panels + [
        StreamFieldPanel('body'),
    ]

这样编辑者就能在Event页面的StreamField中任意位置插入节目单模块,模板也能正确渲染关联的节目条目。

内容的提问来源于stack exchange,提问作者moddayjob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:58:19