使用StreamB时如何解决Wagtail循环块依赖

2024-04-25 05:30:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想取得这样的成就

from wagtail.wagtailcore.blocks import StreamBlock, StructBlock


class CarouselBlock(StructBlock):

    content = StreamBlock([
        ('tab', TabBlock()),
        ('carousel', CarouselBlock())
    ])


class TabBlock(StructBlock):

    content = StreamBlock([
        ('tab', TabBlock()),
        ('carousel', CarouselBlock())
    ])

在旋转木马中,我可以添加一个选项卡或另一个旋转木马,在选项卡中我可以添加一个旋转木马或另一个选项卡。在

处理这样的编程案例的最佳实践是什么。在


Tags: fromcontenttab选项卡classwagtailblockscarousel
1条回答
网友
1楼 · 发布于 2024-04-25 05:30:37

不幸的是,我认为这不可能实现,即使你找到了在定义中设置循环引用的方法。Wagtail的代码中有很多地方会尝试以树的形式遍历定义,最终以无限递归结束。在

例如,在迁移中冻结StreamField定义时会发生这种情况-它会将对命名StructBlock/StreamBlock子类的任何引用扩展为普通StructBlock/StreamBlock构造函数(请参见http://docs.wagtail.io/en/v1.5.2/topics/streamfield.html#streamfield-definitions-within-migrations),在这种情况下,它将无限扩展。类似地,为编辑表单构建HTML也会失败,因为它将尝试为表单中的每个可重复元素构建一个HTML模板(即,每当您单击以添加新的旋转木马或新的选项卡时都要添加的HTML块),而且在顶级旋转木马、二级旋转木马中重复使用相同的模板是不够聪明的,三级旋转木马等等,所以会有无限多的模板生成。在

您要么需要对嵌套的级别设置硬编码限制(例如,CarouselBlock可以包含SecondLevelCarousel块,后者可以包含第三层carousel块,但不能超过这个值),或者想出一种替代的数据表示,将数据条目分散到多个视图中,而不是一个无限嵌套的表单。例如,可以将Carousel和Tab定义为snippet模型,并使用snippechooserblock定义它们之间的父/子链接:

@register_snippet
class Carousel(models.Model):
    content = StreamField([
        ('carousel', blocks.SnippetChooserBlock('myapp.Carousel')),
        ('tab', blocks.SnippetChooserBlock('myapp.Tab')),
    ])

(当然,如果你走这条路,你必须确保不要建立任何循环的父子关系,否则你就回到原点:-)

相关问题 更多 >