【问题标题】:Unable to access values of nested blocks in Streamfield, within Template无法访问模板内 Streamfield 中嵌套块的值
【发布时间】:2016-08-14 16:43:29
【问题描述】:

我是 Wagtail 的新手,但我已经完成了作业并阅读了文档并在网络上搜索了其他参考资料,但无法弄清楚为什么我无法成功循环并渲染输入到 Steamfield 内的各种块中的值。我已经在主页模板和块模板中尝试过。

这是我的模型(agenda_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 %} 

如果我尝试单独访问其中的值,我什么也得不到。以下只是一个示例,但我尝试了许多其他语法组合,包括对名为“agenda_item”的块使用单独的模板均无济于事:

{% if block.block_type == 'item_title' %}

           <h2>{{ block.value }}<h2>

      {% endif %}

我的 Streamfield 嵌套是否有问题,即使它确实保存到数据库并使用简单的 {{block}} 标记呈现?

更新: 我接受了这个答案,因为它解决了我的模板渲染问题,但也许这个屏幕截图将有助于说明我现有的问题。通过单击编辑器界面中的 + 可以使用流块“议程项目”,以将其他子块添加到“议程项目”以及添加新的“议程项目”,这很棒,几乎正是我需要的。问题是我只希望“item_title”可用于新的“agenda_item”,而不适用于“agenda_item”中的孩子。这就是为什么我最初嵌套了流场子级,但后来无法访问模板渲染中的最低级别嵌套块。所以缩小流场的水平解决了这个问题,但现在用户可能会错误地添加一个 item_title ,它不是必需的或无效的。我的问题是:什么可用的流场块(或它们的组合)可能有助于实现这一目标?


(来源:pocketsofactivity.com

我现有的模型和面板定义如下所示:

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'),

]

【问题讨论】:

    标签: django-models wagtail wagtail-streamfield


    【解决方案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_titleitem_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...?)

    【讨论】:

    • 我想我确实希望议程项目成为一个结构块,以便我可以列出一个列表。我将尝试这种子块语法或删除一个级别,在 Wagtail 文档中没有任何地方是我可以找到的单词子块
    • 'subblock' 不是 Wagtail 概念 - 这只是我在该代码示例中选择的变量名,以将其与顶级块区分开来。
    • 此解决方案返回 item_title 值,但我无法正确迭代 structblock:item_content,它得到了这个渲染:[StructValue([('item_text', ' ...etc相同的 for 和 if 语法,有什么想法吗?
    • 我必须使用这种语法来访问 structblock 值,想知道什么时候需要和不需要这个:{{ block.bound_blocks.item_text.render }}
    • 通过将 'item_title' 设为主 'agenda_item' 流块中的可用块,每次在编辑器中单击 + 时它都可用。我需要它只为每个新议程项目显示一次,然后在该项目中单击 + 时只显示其他块
    猜你喜欢
    • 2017-12-26
    • 2017-12-09
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2016-11-27
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多