Определение «последнего» элемента для каждого уровня в django-mptt - PullRequest
3 голосов
/ 06 января 2012

Я пытаюсь создать список, похожий на:

<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 %}

Это прекрасно работает, за исключением того, что последний элемент корневого уровня не получает "последний" класс, потому что его structure.closed_levels всегда пустой список. (Это действительно работает только для дочерних элементов).

Я уверен, что я не первый, кому нужно выполнить нечто подобное, поэтому я надеюсь, что у кого-то здесь уже может быть решение.

Ответы [ 2 ]

1 голос
/ 01 марта 2012

Полагаю, вы сможете получить необходимую информацию из информации о заказе MPTT.Вот хорошее введение в работу MPTT (ссылка на документацию django-mptt).Ключ хранит ссылку на родителя вокруг, так что вы можете проверить, является ли атрибут «right» вашего узла на единицу меньше, чем «left» вашего родителя.

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

С учетом всего сказанного, это слишком много шаблонных вычислений для меня.Если это то, чем вы занимаетесь регулярно, то, вероятно, лучше обернуть это в пользовательский тег шаблона.

0 голосов
/ 12 февраля 2013

Вы должны использовать {{forloop.last}} или {{if 1 == forloop.revcounter}} 2-й последний будет {{if 2 == forloop.revcounter}}

для добавления классов с логикой django ...

если вы просто хотите добавить стили, вы можете использовать css selecotrs :last-child вместо добавления класса

css-селекторы для работы в jquery, если он вам нужен для javascript и используется jquery

...