我想在Django模板中显示一组相关对象的固定长度子集。例如,假设我有一辆汽车,它具有相关的对象所有者。我想显示三个最近的所有者,但即使数量更少,也总是显示三个条目。所以
Ford Fiesta AA11 1AA
1. John Smith
2. Jane Smith
3. Jenny Smith
Aston Martin DB9
1. Richard Rich
2.
3.
即使Fiesta有10个所有者(而DB9只有1个)。
做到这一点的天真的方法是
<h1>{{car.name}}</h1>
<ol>
{% for owner in car.owner_set|slice:":3" %}
<li>{{owner.name}}</li>
{% endfor %}
</ol>
,但是如果只有一个所有者,那么它将仅显示一个列表项。
我也可以添加类似
的行{% if car.owner_set|length < 2 %}<li></li>{% endif %}
{% if car.owner_set|length < 3 %}<li></li>{% endif %}
但这太可怕了。有更好的方法吗?
答案 0 :(得分:3)
在我看来,最简单的方法是定义一个新的过滤器。
在相关应用中创建一个templatetags
包,并使用以下代码添加一个名为liststuff.py
(或您想要的名称)的文件:
from django import template
register = template.Library()
@register.filter
def exactlength(listlike_thing, desired_length):
list_thing = list(listlike_thing)
if len(list_thing) < desired_length:
# pad the list with as many empty strings as needed
list_thing += ([''] * (desired_length - len(list_thing)))
return list_thing[:desired_length]
然后,在模板顶部加载该文件(如果您调用了其他文件,请相应地更改此行):
{% load liststuff %}
并在循环初始化中,将值通过过滤器:
{% for owner in car.owner_set|exactlength:3 %}
答案 1 :(得分:2)
您可以创建一个自定义过滤器或类似的过滤器,但是对于一个实例,我将向Car模型添加一个方法来返回您想要的内容,例如:
def three_latest_owners(self):
num = 3
latest = list(self.owner_set.all()[:num])
latest += [None] * num
return latest[:num]
然后在模板中{% for owner in car.three_latest_owners %}
答案 2 :(得分:2)
显然,不是最优雅的解决方案也不是最可重用的解决方案,但是真正的天真解决方案肯定是:
<h1>{{car.name}}</h1>
<ol>
<li>{{car.owner_set.0.name}}</li>
<li>{{car.owner_set.1.name}}</li>
<li>{{car.owner_set.2.name}}</li>
</ol>