3

我正在尝试生成类似于以下内容的列表:

<ul>
    <li>Parent 1
        <ul>
            <li>Child 1</li>
            <li>Child 2</li>
            <li class="last">Child 3</li>
        </ul>
    </li>
    <li>Parent 2
        <ul>
            <li>Child 1</li>
            <li>Child 2</li>
            <li class="last">Child 3</li>
        </ul>
    </li>
    <li class="last">Parent 3
        <ul>
            <li>Child 1</li>
            <li>Child 2</li>
            <li class="last">Child 3</li>
        </ul>
    </li>
</ul>

我最初只是这样做:

<ul>
    {% recursetree mytree %}
    <li class="{% if not node.get_next_sibling %}last{% endif %}">
        {{ node }}
        {% if not node.is_leaf_node %}
        <ul>
            {{ children }}
        </ul>
        {% endif %}
    </li>
</ul>

但是,对每个项目的调用node.get_next_sibling都会导致额外的查询。显然,这并不理想。所以我尝试使用tree_infoandstructure.closed_levels来确定最后一项:

{% for node,structure in mytree|tree_info %}
    {% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
        <li class="{% if structure.closed_levels|length > 0 %}last{% endif %}">
            {{ node }}
    {% for level in structure.closed_levels %}</li></ul>{% endfor %}
{% endfor %}

这很好用,除了最后一个根级别项目没有获得“最后一个”类,因为它structure.closed_levels始终是一个空列表。(它真的只适用于子项目)。

我确定我不是第一个需要完成类似事情的人,所以我希望这里有人可能已经有了解决方案。

4

2 回答 2

1

我想您应该能够从 MPTT 订单信息中获得所需的信息。这是关于 MPTT 如何工作的一个很好的介绍(链接自 django-mptt 文档)。关键是保持对父节点的引用,因此您可以检查节点的“右”属性是否比父节点的“左”属性小一。

django-mptt 对根节点进行特殊处理,让您拥有多棵树。如果您正在遍历单个树中的节点,那么这样的事情应该可以工作(尽管我还没有测试过):

<ul class="root">
    {% recursetree nodes %}
        <li class="{% if parent == None or node.rgt|plusone == parent.lft %}last{% endif %}">
            {{ node.name }}
            {% if not node.is_leaf_node %}
                {% with node as parent %}
                <ul class="children">
                    {{ children }}
                </ul>
                {% endwith %}
            {% endif %}
        </li>
    {% endrecursetree %}
</ul>

但是,如果“节点”包含所有根的列表,则需要明确地捕获它。这样的事情应该可以解决问题:

{% with nodes|last as lastnode %}
<ul class="root">
    {% recursetree nodes %}
        <li class="{% if node == lastnode or parent and node.rgt|plusone == parent.lft %}last{% endif %}">
            {{ node.name }}
            {% if not node.is_leaf_node %}
                {% with node as parent %}
                <ul class="children">
                    {{ children }}
                </ul>
                {% endwith %}
            {% endif %}
        </li>
    {% endrecursetree %}
</ul>
{% endwith %}

您会注意到上面的代码引用了一个“plusone”模板过滤器。这样的事情应该做:

from django import template

register = template.Library()

@register.filter
def plusone(value):
    return value + 1

话虽如此,这对我来说有点过多的模板计算。如果这是您经常做的事情,最好将其包装在自定义模板标签中。

于 2012-02-29T22:44:09.917 回答
0

您应该使用 the {{forloop.last}} or {{if 1 == forloop.revcounter}} 2nd last 将是{{if 2 == forloop.revcounter}}

用 django 逻辑添加类...

如果您只想添加样式,则可以使用 css 选择器:last-child而不是添加类

如果您需要 javascript 并且正在使用 jquery,则 css 选择器适用于 jquery

于 2013-02-12T14:15:08.727 回答