Невозможно получить доступ к значениям вложенных блоков в Streamfield, в шаблоне
Я новичок в Wagtail, но я выполнил домашнее задание, прочитал документацию и искал в Интернете дополнительные ссылки, но не могу понять, почему я не могу успешно пройтись по ним и отобразить значения, введенные в различные блоки внутри Steamfield. Я пробовал это как в шаблоне главной страницы, так и с шаблоном для блока.
Вот моя модель (шаблон для topic_item закомментирован прямо сейчас):
class AgendaPage(Page):
author= models.CharField(max_length=255)
date = models.DateField('Post date')
agenda = StreamField([
('agenda_item', blocks.StreamBlock([
('item_title', blocks.TextBlock()),
('item_content', blocks.ListBlock(blocks.StructBlock([
('item_text', blocks.TextBlock()),
('mtg_doc', blocks.StructBlock([
('doc_description', blocks.TextBlock()),
('doc_link', blocks.TextBlock())
]))
])))
]
#,
#template='blocks/agenda_temp.html',
))
])
content_panels = Page.content_panels + [
FieldPanel('author'),
FieldPanel('date'),
StreamFieldPanel('agenda'),
]
Когда у меня есть самый простой шаблон, подобный этому, все значения, введенные при публикации страницы в редакторе, отображаются, но с именем предшествующего ему блока. Итак, в этом базовом шаблоне:
{% for block in self.agenda %}
{{ block.value }}
{% endfor %}
Если я пытаюсь получить доступ к значениям по отдельности, я ничего не получаю. Ниже приведен только пример, но я пробовал много других комбинаций синтаксиса, в том числе использование отдельного шаблона для блока с именем "повестки дня" безрезультатно:
{% if block.block_type == 'item_title' %}
<h2>{{ block.value }}<h2>
{% endif %}
Возможно, что-то не так с моим вложением Streamfield, даже если оно сохраняется в базе данных и отображается с помощью простого тега {{block}}?
ОБНОВЛЕНИЕ: Я принял этот ответ, потому что он решил мои проблемы с рендерингом шаблона, но, возможно, этот скриншот поможет проиллюстрировать мою существующую проблему. Стробблок "повестки дня" можно получить, нажав кнопку "+" в интерфейсе редактора, чтобы добавить дополнительные дочерние блоки к "повестке дня", а также добавить новый "повестка дня", который великолепен и почти точно соответствует тому, что мне нужно. Проблема в том, что я хочу, чтобы элемент item_title был доступен только для нового элемента повестки дня, а не для детей в рамках элемента повестки дня. Вот почему я изначально вложил дочерние потоки как таковые, но потом не смог получить доступ к вложенному блоку самого низкого уровня при рендеринге шаблона. Таким образом, уменьшение уровней потокового поля решило проблему, но теперь пользователь может по ошибке добавить элемент item_title там, где он не нужен или не действителен. Мой вопрос: какой доступный блок потокового поля (или их комбинация) может помочь в этом?
http://pocketsofactivity.com/scrnsht.jpg
Мои существующие определения моделей и панелей выглядят так:
agenda = StreamField([
('agenda_item', blocks.StreamBlock([
('item_title', blocks.TextBlock()),
('item_text', blocks.TextBlock()),
('mtg_doc', blocks.StructBlock([
('mtg_doc_upload', DocumentChooserBlock(required=True)),
('submitted_late', blocks.BooleanBlock(required=False, help_text='Submitted Late')),
('heldover', blocks.BooleanBlock(required=False, help_text='Held Over')),
('heldover_from', blocks.DateBlock(required=False, help_text="Held Over From")),
])),
('item_audio', DocumentChooserBlock(required=False)),
]))
])
content_panels = Page.content_panels + [
FieldPanel('author'),
FieldPanel('date'),
FieldPanel('mtg_date'),
FieldPanel('mtg_time'),
StreamFieldPanel('mtg_media'),
StreamFieldPanel('agenda'),
]
1 ответ
В способе написания вашего кода блоки верхнего уровня всегда имеют тип agenda_item
так что вам нужно учесть это при их цикле:
{% for block in self.agenda %}
{% if block.block_type == 'agenda_item' %} {# will always be true, but included here for clarity #}
{% for subblock in block.value %}
{% if subblock.block_type == 'item_title' %}
<h2>{{ subblock.value }}</h2>
{% elif subblock.block_type == 'item_content' %}
rendering for item_content...
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
Тем не менее, я не думаю, что вам действительно нужно agenda_item
StreamBlock вообще - это просто добавление ненужного уровня косвенности, которое сбивает вас с толку. Насколько я вижу, вы можете достичь того же результата, просто сделав item_title
а также item_content
два доступных типа блоков на верхнем уровне:
agenda = StreamField([
('item_title', blocks.TextBlock()),
('item_content', blocks.ListBlock(blocks.StructBlock([
('item_text', blocks.TextBlock()),
('mtg_doc', blocks.StructBlock([
('doc_description', blocks.TextBlock()),
('doc_link', blocks.TextBlock())
]))
])))
])
(Или ты намеревался agenda_item
вместо StructBlock...?)