在Django模板中显示列表的固定长度子集

时间:2019-06-23 15:09:49

标签: django django-templates

我想在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 %}

但这太可怕了。有更好的方法吗?

3 个答案:

答案 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>