gpt4 book ai didi

python - 使用 StreamBlock 时如何解决 Wagtail 循环 block 依赖

转载 作者:太空宇宙 更新时间:2023-11-03 15:01:09 25 4
gpt4 key购买 nike

我想实现这样的目标,

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())
])

在 Carousel 中,我可以添加一个选项卡或另一个 carousel,在一个 Tab 内我可以添加一个 carousel 或另一个 Tab。

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

最佳答案

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

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

您需要对嵌套层数设置硬编码限制(例如,CarouselBlock 可以包含一个 SecondLevelCarousel block ,该 block 可以包含一个 ThirdLevelCarousel block ,但仅此而已),或者想出一个替代方案将数据条目分散到多个 View 而不是单个无限嵌套表单的数据表示。例如,您可以将 Carousel 和 Tab 定义为片段模型,并使用 SnippetChooserBlock 定义它们之间的父/子链接:

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

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

关于python - 使用 StreamBlock 时如何解决 Wagtail 循环 block 依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37833593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com