无法在模板

时间:2016-08-14 16:43:29

标签: django-models wagtail wagtail-streamfield

我是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}}标记进行渲染?

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

Valid XHTML 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 个答案:

答案 0 :(得分:2)

在您的代码当前编写方式中,您的顶级块始终为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而不是......?)