Как получить идентификатор базы данных из struct_block.StructValue в шаблоне блока трясогузки?

Создание собственного шаблона для трясогузки StreamField Блок Я попал в ситуацию, в которой мне нужно как-то передать идентификатор текущего блока другим представлениям.

Например, когда URL-адрес нажимается в конкретном блоке, целевая страница view должен точно знать, в каком из блоков был нажат URL. Тогда view может извлекать другую информацию, которая связана с конкретным блоком, но не обязательно визуально представлена ​​пользователю.

Моя текущая стратегия использует snippetsтак что я могу передать идентификатор snippet и view может получить связанные, но заранее скрытые данные.

Это работает не так уж плохо, но люди должны редактировать контент в двух местах, и я должен смотреть на их грустные лица.

Кажется, что value переменная в контексте шаблона блока является экземпляром wagtail.core.blocks.struct_block.StructValue, который дает мне доступ ко всем полям блока, но, похоже, не показывает его след в БД.

В дальнейшем value имеет интересный атрибут: value.blockКажется, это экземпляр реальной модели, использованной для построения блока, но опять же я не могу найти ничего полезного, например, id или же pk что позволило бы идентифицировать этот экземпляр в базе данных.

Есть ли способ?

1 ответ

Решение

Идентификаторы блоков, которые вы видите в представлении базы данных StreamField, являются подробностями, реализованными включающим StreamBlock, так что мы можем отслеживать историю каждого блока, когда он добавляется / перемещается / удаляется из потока. Элементы в потоке не знают своего собственного идентификатора - это потому, что они могут быть любого возможного типа данных (например, CharBlock создает строковое значение, и вы не можете прикрепить идентификатор к строке). В результате шаблон блока также не имеет доступа к идентификатору.

Чтобы получить доступ к идентификатору, вам необходимо использовать BoundBlock (или, точнее, StreamChild) объект, который возвращается всякий раз, когда вы перебираете значение StreamField (или обращаетесь к нему по индексу, например, page.body[0] или же page.body.0 в коде шаблона); этот объект является оберткой вокруг значения блока, который знает тип и идентификатор блока. (Больше информации на BoundBlock в документации здесь: http://docs.wagtail.io/en/v2.0/topics/streamfield.html)

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

Вот block это пример StreamChild, который имеет свойства 'value', 'block_type' и 'id'. Обычно {% include_block %} тег будет просто передавать на value переменная в шаблоне блока, но здесь мы проходим id в качестве дополнительной переменной, которая теперь будет доступна в этом блочном шаблоне.

Блоки StreamField не являются "реальными" объектами базы данных, поэтому для получения значения снова на основе идентификатора вам нужно будет сканировать через StreamField, используя такой код, как:

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 %}
Другие вопросы по тегам