模板中的数学运算

时间:2018-11-04 16:42:33

标签: django django-templates

在布局中,我有预定义数量的展示位置/空间。

我想用图像填充它,但是在某些情况下,没有图像或更少图像:

当有足够的图像时,可以使用以下代码:

{% for placement in placement_list %}
        <a href="{{ placement.url }}">
            <img src="{{ MEDIA_URL }}{{ placement.image }}"/>
        </a>
 {% endfor %}

但是当图像的数量为零或少于布局中的可用空间时,我要显示默认图像/

我知道我可以使用{{placement_list | length}}

检查长度

我想要类似的东西

 for i to (MAX_NR_placements - {{ placement_list|length }})
       <img src="default" />

1 个答案:

答案 0 :(得分:1)

我讨厌自己是那个StackOverflow用户,他说“不要那样做,那样做”来回答一个问题,但是……不要那样做,就这样做:

Django确实鼓励您在视图中执行这种逻辑。您“应该”将placement_list填充到正确的长度,然后再将其发送到模板进行渲染。

您说placement_list当前是在视图中定义的查询集,然后按原样发送到模板。假设您当前的执行方式看起来像这样:

placement_list = MyModel.objects.all()

如果我们希望该长度至少为50个项目怎么办?我们可以将placement_list从查询集转换为列表,然后将伪MyModel对象添加到该数组。

padded_placements = placement_list + [MyModel()]*(50-len(placement_list))

请注意,我们在此处实例化MyModel()对象,但实际上并未执行Django风格的create和/或将任何内容保存到数据库。这些是空的“虚拟”对象,我们可以将其发送到模板以用作占位符,而不会污染我们的真实数据。

让我们对刚写的行进行一些调整,以使模板制作更容易:

padded_placements = placement_list + [MyModel(url='DEFAULT')]*(50-len(placement_list))

现在,我们所有的虚拟对象都将其url属性设置为字符串DEFAULT。这不会通过对象级URL验证,但这没关系,因为我们没有将这些虚拟变量保存到数据库中-这些验证器永远不会被调用。

padded_placements发送到模板,然后查找我们的自定义属性:

{% for placement in padded_placements %}
    {% if placement.url != 'DEFAULT' %}
        <a href="{{ placement.url }}">
            <img src="{{ MEDIA_URL }}{{ placement.image }}"/>
        </a>
    {% else %}
        <p>do default stuff</p>
    {% endif %}
 {% endfor %}

两个注意事项:

  • 您的虚拟MyModel对象可能需要设置其他属性,具体取决于这些对象如何在模板中使用以及模型如何表示自身。例如,如果您的str / repr方法依赖于MyModel.description,则需要包括该字段。

  • 将列表而不是查询集传递给模板意味着您将无法访问模板中的查询集内容。真是太好了,因为您实际上正在执行任何查询集类型的逻辑(过滤,exists检查等),所以REALLY应该在视图中而不是在模板中完成。