我正在尝试创建一个块,该块允许我添加多个块,其中每个块在大小估计器中都是不同的大小。
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_type
和value
属性的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 %}
了。