如何从 wagtail 块模板中的 struct_block.StructValue 获取数据库 ID?
How to obtain database id from the struct_block.StructValue in the wagtail block template?
为 wagtail StreamField
块构建自定义模板我发现自己处于需要以某种方式将当前块的 ID 传递给其他视图的情况。
例如,当 URL 在特定区块中被点击时,着陆页 view
必须准确知道 URL 在哪个区块中被点击。然后 view
可以提取与特定块相关联但不一定在视觉上呈现给用户的其他信息。
我目前的策略是使用snippets
,所以我可以通过snippet
的ID,view
可能会获得相关但事先隐藏的数据。
这个效果还不错,但是人们不得不在两个地方编辑内容,我不得不看他们悲伤的脸。
似乎块模板上下文中的 value
变量是 wagtail.core.blocks.struct_block.StructValue
的一个实例,它使我可以访问块的所有字段,但似乎没有显示它在数据库中的足迹。
此外 value
有一个有趣的属性:value.block
,它似乎是用于构建块的实际模型的实例,但我还是找不到任何有用的东西,比如 id
或 pk
允许在数据库中识别该实例。
有办法吗?
您在 StreamField 的数据库表示中看到的块 ID 是由封闭的 StreamBlock 实现的细节,因此我们可以跟踪每个块在流中添加/移动/删除时的历史记录。流中的项目不知道它们自己的 ID - 这是因为它们可能是任何可能的数据类型(例如,CharBlock
产生一个字符串值,并且您不能将 ID 附加到字符串)。因此,块模板也无法访问 ID。
要访问 ID,您需要使用每次迭代 StreamField 值(或访问它)时返回的 BoundBlock
(或更准确地说,StreamChild
)对象按索引,例如模板代码中的 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 块不是 'real' 数据库对象,因此要根据您需要扫描 StreamField 的 ID 再次检索值,使用如下代码:
value = None
for block in page.body:
if block.id == requested_id:
value = block.value
break
在显示您的区块的 HTML 文件中,尝试添加
{% with block.id|stringformat:"s" as block_id %}
{{ block_id }}
{% endwith %}
为 wagtail StreamField
块构建自定义模板我发现自己处于需要以某种方式将当前块的 ID 传递给其他视图的情况。
例如,当 URL 在特定区块中被点击时,着陆页 view
必须准确知道 URL 在哪个区块中被点击。然后 view
可以提取与特定块相关联但不一定在视觉上呈现给用户的其他信息。
我目前的策略是使用snippets
,所以我可以通过snippet
的ID,view
可能会获得相关但事先隐藏的数据。
这个效果还不错,但是人们不得不在两个地方编辑内容,我不得不看他们悲伤的脸。
似乎块模板上下文中的 value
变量是 wagtail.core.blocks.struct_block.StructValue
的一个实例,它使我可以访问块的所有字段,但似乎没有显示它在数据库中的足迹。
此外 value
有一个有趣的属性:value.block
,它似乎是用于构建块的实际模型的实例,但我还是找不到任何有用的东西,比如 id
或 pk
允许在数据库中识别该实例。
有办法吗?
您在 StreamField 的数据库表示中看到的块 ID 是由封闭的 StreamBlock 实现的细节,因此我们可以跟踪每个块在流中添加/移动/删除时的历史记录。流中的项目不知道它们自己的 ID - 这是因为它们可能是任何可能的数据类型(例如,CharBlock
产生一个字符串值,并且您不能将 ID 附加到字符串)。因此,块模板也无法访问 ID。
要访问 ID,您需要使用每次迭代 StreamField 值(或访问它)时返回的 BoundBlock
(或更准确地说,StreamChild
)对象按索引,例如模板代码中的 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 块不是 'real' 数据库对象,因此要根据您需要扫描 StreamField 的 ID 再次检索值,使用如下代码:
value = None
for block in page.body:
if block.id == requested_id:
value = block.value
break
在显示您的区块的 HTML 文件中,尝试添加
{% with block.id|stringformat:"s" as block_id %}
{{ block_id }}
{% endwith %}