Working with trees in templates
Getting started
Before you can use these tags/filters, you must:
add “mptt” to your
INSTALLED_APPS
insettings.py
add
{% load mptt_tags %}
in your template.
Filters
tree_info
filter
Given a list of tree items, iterates over the list, generating
two-tuples of the current tree item and a dict
containing
information about the tree structure around the item, with the following
keys:
'new_level'
True
if the current item is the start of a new level in the tree,False
otherwise.'closed_levels'
A list of levels which end after the current item. This will be an empty list if the next item’s level is the same as or greater than the level of the current item.
An optional argument can be provided to specify extra details about the
structure which should appear in the dict
. This should be a
comma-separated list of feature names. The valid feature names are:
- ancestors
Adds a list of unicode representations of the ancestors of the current node, in descending order (root node first, immediate parent last), under the key
'ancestors'
.For example: given the sample tree below, the contents of the list which would be available under the
'ancestors'
key are given on the right:Books -> [] Sci-fi -> ['Books'] Dystopian Futures -> ['Books', 'Sci-fi']
Using this filter with unpacking in a {% for %}
tag, you should have
enough information about the tree structure to create a hierarchical
representation of the tree.
Example:
{% for genre,structure in genres|tree_info %}
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
{{ genre.name }}
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
{% endfor %}
tree_path
Creates a tree path represented by a list of items by joining the items
with a separator, which can be provided as an optional argument,
defaulting to ' :: '
.
Each path item will be coerced to unicode, so a list of model instances may be given if required.
Example:
{{ some_list|tree_path }}
{{ some_node.get_ancestors|tree_path:" > " }}
Examples
Using drilldown_tree_for_node
and tree_info
together to render a
drilldown menu for a node, with cumulative counts of related items for the node’s
children:
{% drilldown_tree_for_node genre as drilldown cumulative count tests.Game.genre in game_count %}
{% for node,structure in drilldown|tree_info %}
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
{% if node == genre %}
<strong>{{ node.name }}</strong>
{% else %}
<a href="{{ node.get_absolute_url }}">{{ node.name }}</a>
{% if node.parent_id == genre.pk %}({{ node.game_count }}){% endif %}
{% endif %}
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
{% endfor %}
Using tree_info
(with its optional argument) and tree_path
together
to create a multiple-select, which:
doesn’t contain root nodes
displays the full path to each node
<select name="classifiers" multiple="multiple" size="10">
{% for node,structure in classifiers|tree_info:"ancestors" %}
{% if node.is_child_node %}
<option value="{{ node.pk }}">
{{ structure.ancestors|tree_path }} :: {{ node }}
</option>
{% endif %}
{% endfor %}
</select>