【问题标题】:How to obtain database id from the struct_block.StructValue in the wagtail block template?如何从 wagtail 块模板中的 struct_block.StructValue 获取数据库 ID?
【发布时间】:2018-08-29 15:18:22
【问题描述】:

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

例如,当在特定块中点击 URL 时,着陆页 view 必须准确知道在哪个块中点击了 URL。然后view 可以提取与特定块相关但不一定直观地呈现给用户的其他信息。

我目前的策略是使用snippets,所以我可以通过snippet的ID,view可以获取相关但预先隐藏的数据。

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

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

另外value 有一个有趣的属性:value.block,这似乎是用于构建块的实际模型的一个实例,但我还是找不到像 idpk 这样有用的东西将允许在数据库中识别该实例。

有办法吗?

【问题讨论】:

    标签: django python-3.x wagtail wagtail-streamfield wagtail-snippet


    【解决方案1】:

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

    要访问 ID,您需要使用在迭代 StreamField 值时返回的 BoundBlock(或更准确地说,StreamChild)对象(或通过索引访问它,例如 @987654325 @ 或 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 %}
    

    这里的blockStreamChild 的一个实例,它具有'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
    

    【讨论】:

    • 谢谢,我能够检索到一些看起来像块 ID 的东西(它看起来像 uuid4)。您能否详细说明一下,如何使用它来提取字段值?此外,是否有必要通过StreamField 进行迭代?当您只需要插入一项时,这似乎完全违反直觉,但我认为include_block 在检测到StreamField 时会在内部这样做?
    • 您不必遍历StreamField - 如果您知道您感兴趣的特定块,您可以通过索引访问它,例如page.body[0](或模板代码中的page.body.0)。已更新我的答案以涵盖在另一端检索值。
    • 谢谢,知道这很有用。但是我仍然看不到如何使用该 ID 从blocks.StructBlock 中提取字段值?如果您愿意,viewwagtail 之外,并且必须使用已传递给它的 block_id 自行查询数据库。
    • Jinja2 呢? include_block with… 的技巧不起作用,即使我们使用包裹在 with block_id=block.id 中的 include_block with context :(
    【解决方案2】:

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

    {% with block.id|stringformat:"s" as block_id %}
     {{ block_id }}
    {% endwith %}
    

    【讨论】:

    • 欢迎来到 SO!在回答一个已经被接受的答案(这里就是这种情况)的老问题(这里是 2 岁以上)之前,请先问问自己:我真的有什么新的东西要补充吗?如果没有,请不要回答。
    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 2011-02-10
    • 2017-12-24
    • 2016-10-20
    • 1970-01-01
    • 2019-12-03
    • 2021-11-09
    • 1970-01-01
    相关资源
    最近更新 更多