我正在尝试生成类似于以下内容的列表:
<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_info
和structure.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 %}
这很好用,除了最后一个根级别项没有获得“last”类,因为它的structure.closed_levels
始终是一个空列表。 (它真的只适用于儿童用品)。
我确信我不是第一个需要完成类似工作的人,所以我希望这里有人可能已经有了解决方案。
答案 0 :(得分:1)
我想您应该能够从MPTT订单信息中获取所需信息。这是一个good intro to how MPTT works(从django-mptt docs链接)。关键是保持对父母的引用,这样你就可以检查你的节点的“正确”属性是否比你父母的“左”少一个。
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>
但是,如果“nodes”包含所有根的列表,则需要明确捕获它。这样的事情可以解决问题:
{% 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
所有这一切,根据我的喜好,这是一个太多的模板计算。如果这是你经常做的事情,将它包装在自定义模板标签中可能是明智的。
答案 1 :(得分:0)
你应该使用{{forloop.last}}
或{{if 1 == forloop.revcounter}}
最后一个是{{if 2 == forloop.revcounter}}
使用django逻辑添加类...
如果您只是想添加样式,可以使用css选择器:last-child
而不是添加类
选择器来为jquery工作