Wagtail 管理员:如何添加 ReadOnlyBlocks 以在 StructBlock 中显示片段字段值

Wagtail Admin: How to Add ReadOnlyBlocks to show snippets fields values in a StructBlock

我有一个带有字段 field_a、field_b 和 field_c 的代码段模型 (SampleSnippet)。我在 StructBlock 中使用它,例如:

class SampleBlock(blocks.StructBlock):
    service_snippet = SnippetChooserBlock(SampleSnippet)
    ...

现在我想在第一次保存 SampleBlock 后(在保存snippet) 在 wagtail 管理站点上。我怎样才能做到这一点?我环顾四周,但找不到类似的问题。

如果它是 model/snippet,我可以将 属性 与 ReadOnlyPanel 一起使用,但在 StructBlock 的情况下,我被卡住了,没有任何想法。如果有人知道实现这一目标的任何方法,请帮助我。提前致谢。

这将非常困难,因为在当前的 Wagtail 版本 (>=2.13) 中,StreamField 编辑 UI 在 Javascript 中填充 client-side - 因此,有一些额外的步骤使必要的数据可用于 client-side 代码,标准的 Django 表单/模板机制将不可用。

如果字段不是太长,一个简单的解决方法是定义代码段的 __str__ 方法以包含所需数据 - 然后,只要代码段在管理中显示,就会显示该方法。

对于完整的解决方案,我建议采用这种方法:

  • 为您的 StructBlock 设置自定义 form_template,详见 Custom editing interfaces for StructBlock,使用占位符 <div> 元素来包含您的附加数据。

  • 覆盖 StructBlock 的 get_form_state 以便返回的字典(将用于在客户端填充表单模板)包括您的附加字段 - 例如:

    def get_form_state(self, value):
        data = super().get_form_state(value)
        data['field_a'] = value['service_snippet'].field_a
        data['field_b'] = value['service_snippet'].field_b
        return data
    
  • 按照 Additional JavaScript on StructBlock forms 中的步骤设置自定义 JS 适配器。在最后的 render 方法中,您从 get_form_state 返回的数据将作为 initialState 提供,您可以使用它来填充模板中的占位符 <div>