Невозможно получить доступ к значениям вложенных блоков в 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...?)

Другие вопросы по тегам