Python 使用StreamBlock时如何解决Wagtail循环块依赖关系

Python 使用StreamBlock时如何解决Wagtail循环块依赖关系,python,django,wagtail,wagtail-streamfield,Python,Django,Wagtail,Wagtail Streamfield,我想实现这样的目标 from wagtail.wagtailcore.blocks import StreamBlock, StructBlock class CarouselBlock(StructBlock): content = StreamBlock([ ('tab', TabBlock()), ('carousel', CarouselBlock()) ]) class TabBlock(StructBlock): c

我想实现这样的目标

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())
    ])
在旋转木马中,我可以添加一个选项卡或另一个旋转木马,在选项卡中,我可以添加一个旋转木马或另一个选项卡


处理此类编程案例的最佳实践是什么。

不幸的是,我认为这不可能实现,即使您找到了在定义中设置循环引用的方法。Wagtail的代码中有许多地方会尝试将定义作为一棵树进行遍历,并以无限递归结束

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

您需要对嵌套级别的数量设置硬编码限制(例如,旋转木马可以包含第二级旋转木马块,该块可以包含第三级旋转木马块,但不能超过该限制),或者提出一种替代的数据表示法,将数据条目分散到多个视图中,而不是一个无限嵌套的表单。例如,您可以将转盘和选项卡定义为代码段模型,并使用SnippetChooserBlock定义它们之间的父/子链接:

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

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

让我试试,我会让你知道这是怎么回事。我不知道
('tab',blocks.SnippetChooserBlock('myapp.tab'))
最新的Wagtail版本中提供了使用字符串表示法引用模型的功能。尽管我看到了这方面的PR。代码段是否可以有自己的模板?使用为我设计的代码段模型,我希望这是可以使用StreamField或NestedStreamField之类的新类型巧妙完成的