6

为 wagtail 块构建自定义模板StreamField我发现自己处于需要以某种方式将当前块的 ID 传递给其他视图的情况。

例如,当在特定块中单击 URL 时,登录页面view必须准确知道该 URL 是在哪个块中被单击的。然后view可以提取与特定块相关联但不一定在视觉上呈现给用户的其他信息。

我目前的策略是使用snippets,所以我可以传递 的 IDsnippet并且view可以获得相关但事先隐藏的数据。

这工作还不错,但人们必须在两个地方编辑内容,我必须看看他们悲伤的脸。

似乎value块模板上下文中的变量是 的一个实例wagtail.core.blocks.struct_block.StructValue,它使我可以访问块的所有字段,但它似乎没有显示它在数据库中的足迹。

此外value还有一个有趣的属性:value.block,它似乎是用于构造块的实际模型的一个实例,但我再次找不到任何有用的东西,例如idpk允许在数据库中识别该实例。

有办法吗?

4

2 回答 2

6

您在 StreamField 的数据库表示中看到的块 ID 是由封闭的 StreamBlock 实现的细节,因此我们可以跟踪每个块的历史记录,因为它从流中添加/移动/删除。流中的项目不知道它们自己的 ID - 这是因为它们可以是任何可能的数据类型(例如,aCharBlock产生一个字符串值,并且您不能将 ID 附加到字符串)。因此,块模板也无权访问该 ID。

要访问 ID,您需要使用BoundBlock(或者更准确地说,StreamChild)对象,该对象在您迭代 StreamField 值(或通过索引访问它,例如page.body[0]page.body.0在模板代码中)时返回;这个对象是块值的包装器,它知道块的类型和 ID。BoundBlock(此处文档的更多背景信息:http: //docs.wagtail.io/en/v2.0/topics/streamfield.html#boundblocks-and-values

{% for block in page.body %}
    {% include_block block with id=block.id %}
{% endfor %}

block是 的一个实例StreamChild,它具有 'value'、'block_type' 和 'id' 属性。通常,{% include_block %}标签只会将value变量传递给块模板,但在这里我们将id作为附加变量传递,该变量现在可以在该块模板中使用。

StreamField 块不是“真正的”数据库对象,因此要根据 ID 再次检索值,您需要使用以下代码扫描 StreamField:

value = None
for block in page.body:
    if block.id == requested_id:
        value = block.value
        break
于 2018-03-20T19:34:33.157 回答
0

在显示您的块的 HTML 文件中,尝试添加

{% with block.id|stringformat:"s" as block_id %}
 {{ block_id }}
{% endwith %}
于 2020-10-10T02:43:43.240 回答