Wagtail流块模板渲染

  • 本文关键字:Wagtail django wagtail
  • 更新时间 :
  • 英文 :


我正在尝试创建一个块,该块允许我添加多个块,其中每个块在大小估计器中都是不同的大小。

class SizeItem(blocks.StructBlock):
name = blocks.CharBlock(required=True)
image = ImageChooserBlock(required=True)
description = blocks.TextBlock(required=True)
class Meta: #noqa
icon = 'arrows-up-down'
label = 'Size Estimator Item'

class SizeEstimator(blocks.StructBlock):
description = blocks.TextBlock(required=False)
size_items = blocks.StreamBlock([
('size_item', SizeItem())
], required=False)
class Meta: #noqa
template = 'streams/size_estimator.html'
icon =  'list-ul'
label = 'Size Estimator'

问题是,我需要在SizeEstimator模板的不同区域内分组的名称、图像和描述:

<div>
<div>
<ul>
<li>names</li>
</ul>
</div>
<div>
<div>
images
</div>
</div>
<div>
descritions
</div>
</div>

所以我不能在SizeItem上使用模板,因为没有办法在SizeEstimator模板中分离各个部分。但如果我尝试:

<div class="se-wrap flexy">
<div class="se-sizes">
{% for item in self.size_items %}
<div class="se-size-btn">
{{item}}
</div>
{% endfor %}
</div>
</div>

我得到每个SizeItem属性名称和值的纯文本。我不能只提取像item.name这样的值,因为输出是空白的。

将可排序块添加到另一个块中的好方法是什么?在这个块中,您可以拼凑出可排序块的内容?

由于您已将size_items定义为StreamBlock,因此在self.size_items上循环将为您提供具有block_typevalue属性的StreamChild对象序列。在这种情况下,block_type将始终是'size_item'(因为这是该流中定义的唯一块类型),而value将是一个SizeItem的数据,作为dict。因此,您可以使用以下模板访问该项的各个字段:

<div class="se-wrap flexy">
<div class="se-sizes">
{% for item in self.size_items %}
<div class="se-size-btn">
{{item.value.name}}
</div>
{% endfor %}
</div>
<div class="se-images">
{% for item in self.size_items %}
<div class="se-size-btn">
{% image item.value.image width-400 %}
</div>
{% endfor %}
</div>
</div>

如果您将size_items定义为size_items = blocks.ListBlock(SizeItem(), required=False),这将简化事情,因为ListBlock直接返回子值列表-没有中间的StreamChild对象来标识每个块的类型,因此您可以在模板中编写{{item.name}}

与其拆包模板中的数据,不如在SizeEstimator块中添加一个get_context方法,该方法设置了一些要传递给模板的变量:

class SizeEstimator(blocks.StructBlock):
# ...
def get_context(self, value, parent_context=None):
context = super().get_context(value, parent_context=parent_context)
names = []
images = []
descriptions = []
for item in value:
names.append(item.value['name'])  # or item['name'] if you're using a ListBlock
images.append(item.value['image'])
descriptions.append(item.value['description'])
# make these lists available to the template
context['names'] = name
context['images'] = images
context['descriptions'] = descriptions
return context

然后,您就可以在模板中编写{% for name in names %}了。

最新更新