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

如何通过Django管理命令在Wagtail中编程添加List/StructBlock?

问题描述

我是Wagtail新手,正尝试通过Django管理命令编程创建内容。我定义了如下StructBlock和包含StreamField的Page:

class TaskBlock(blocks.StructBlock):
    tasks = blocks.ListBlock(
        blocks.StructBlock(
            [
                ("title", blocks.CharBlock()),
                ("length", blocks.IntegerBlock())
            ]
        )
    )

    class Meta:
        template = "tasks/task_block.html"
        icon = "edit"
        label = "Task"


class TaskPage(Page):
    tasks_first = StreamField([("tasks_first", TaskBlock())], null=True)

    content_panels = Page.content_panels + [StreamFieldPanel("tasks_first")]

我的命令代码如下:

class Command(BaseCommand):
    def handle(self, *args, **options):
        parent_page = Page.objects.get(title="Task Master").specific
        task_page = TaskPage(
            title="Task Page 5",
            slug="task-page-5",
            tasks_first=json.dumps(
                [
                    {
                        "type": "tasks_first",
                        "value": [
                            {
                                "type": "tasks",
                                "value": [
                                    {"type": "title", "value": "this is a task"},
                                    {"type": "length", "value": 5}
                                ],
                            }
                        ],
                    }
                ]
            ),
        )
        parent_page.add_child(instance=task_page)
        revision = task_page.save_revision()
        revision.publish()
        task_page.save()

页面成功创建并带有Task块,但任务内容为空,未显示JSON中定义的测试数据。

解决方案

问题出在你对StructBlock和ListBlock的JSON格式理解有误,正确格式需遵循Wagtail StreamField的嵌套规则:

  • StructBlock的value是字典:TaskBlock作为StructBlock,它的value应为键值对字典,键对应你定义的字段名tasks,而非列表。
  • ListBlock的value是对象列表:tasks字段是ListBlock,它的value是包含多个子StructBlock数据的列表,每个子项直接用字典存储title和length字段,不需要额外的type标识。

修正后的JSON格式版本

import json
from django.core.management.base import BaseCommand
from wagtail.models import Page
from your_app.models import TaskPage  # 替换为实际app名称

class Command(BaseCommand):
    def handle(self, *args, **options):
        parent_page = Page.objects.get(title="Task Master").specific
        task_page = TaskPage(
            title="Task Page 5",
            slug="task-page-5",
            tasks_first=json.dumps(
                [
                    {
                        "type": "tasks_first",
                        "value": {
                            "tasks": [
                                {"title": "this is a task", "length": 5},
                                {"title": "another task", "length": 10}
                            ]
                        },
                    }
                ]
            ),
        )
        parent_page.add_child(instance=task_page)
        revision = task_page.save_revision()
        revision.publish()
        task_page.save()

更可靠的非JSON写法(推荐)

直接使用Wagtail提供的StreamValue和块实例构建数据,避免手动编写JSON的格式错误:

from wagtail.models import Page, StreamValue
from your_app.models import TaskPage, TaskBlock  # 替换为实际app名称

class Command(BaseCommand):
    def handle(self, *args, **options):
        parent_page = Page.objects.get(title="Task Master").specific
        
        # 构建TaskBlock数据
        task_block_data = {
            "tasks": [
                {"title": "this is a task", "length": 5},
                {"title": "another task", "length": 10}
            ]
        }
        task_block = TaskBlock()
        stream_data = [("tasks_first", task_block.to_python(task_block_data))]
        
        task_page = TaskPage(
            title="Task Page 5",
            slug="task-page-5",
            tasks_first=StreamValue(TaskPage.tasks_first.field, stream_data, is_lazy=True)
        )
        
        parent_page.add_child(instance=task_page)
        revision = task_page.save_revision()
        revision.publish()
        task_page.save()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:30:51