API¶

- class treebeard.models.Node(*args, **kwargs)¶
Bases:
django.db.models.base.Model
Node class
This is the base class that defines the API of all tree models in this library:
treebeard.mp_tree.MP_Node
(materialized path)treebeard.ns_tree.NS_Node
(nested sets)treebeard.al_tree.AL_Node
(adjacency list)
Warning
Please be aware of the Known Caveats when using this library.
- classmethod add_root(**kwargs)¶
Adds a root node to the tree. The new root node will be the new rightmost root node. If you want to insert a root node at a specific position, use
add_sibling()
in an already existing root node instead.- Parameters
**kwargs – object creation data that will be passed to the inherited Node model
instance – Instead of passing object creation data, you can pass an already-constructed (but not yet saved) model instance to be inserted into the tree.
- Returns
the created node object. It will be save()d by this method.
- Raises
NodeAlreadySaved – when the passed
instance
already exists in the database
Example:
MyNode.add_root(numval=1, strval='abcd')
Or, to pass in an existing instance:
new_node = MyNode(numval=1, strval='abcd') MyNode.add_root(instance=new_node)
- add_child(**kwargs)¶
Adds a child to the node. The new node will be the new rightmost child. If you want to insert a node at a specific position, use the
add_sibling()
method of an already existing child node instead.- Parameters
**kwargs – Object creation data that will be passed to the inherited Node model
instance – Instead of passing object creation data, you can pass an already-constructed (but not yet saved) model instance to be inserted into the tree.
- Returns
The created node object. It will be save()d by this method.
- Raises
NodeAlreadySaved – when the passed
instance
already exists in the database
Example:
node.add_child(numval=1, strval='abcd')
Or, to pass in an existing instance:
new_node = MyNode(numval=1, strval='abcd') node.add_child(instance=new_node)
- add_sibling(pos=None, **kwargs)¶
Adds a new node as a sibling to the current node object.
- Parameters
pos –
The position, relative to the current node object, where the new node will be inserted, can be one of:
first-sibling
: the new node will be the new leftmost siblingleft
: the new node will take the node’s place, which will be moved to the right 1 positionright
: the new node will be inserted at the right of the nodelast-sibling
: the new node will be the new rightmost siblingsorted-sibling
: the new node will be at the right position according to the value of node_order_by
**kwargs – Object creation data that will be passed to the inherited Node model
instance – Instead of passing object creation data, you can pass an already-constructed (but not yet saved) model instance to be inserted into the tree.
- Returns
The created node object. It will be saved by this method.
- Raises
InvalidPosition – when passing an invalid
pos
parmInvalidPosition – when
node_order_by
is enabled and thepos
parm wasn’tsorted-sibling
MissingNodeOrderBy – when passing
sorted-sibling
aspos
and thenode_order_by
attribute is missingNodeAlreadySaved – when the passed
instance
already exists in the database
Examples:
node.add_sibling('sorted-sibling', numval=1, strval='abc')
Or, to pass in an existing instance:
new_node = MyNode(numval=1, strval='abc') node.add_sibling('sorted-sibling', instance=new_node)
- delete()¶
Removes a node and all it’s descendants.
Note
Call our queryset’s delete to handle children removal. Subclasses will handle extra maintenance.
- classmethod get_tree(parent=None)¶
- Returns
A list of nodes ordered as DFS, including the parent. If no parent is given, the entire tree is returned.
- get_depth()¶
- Returns
the depth (level) of the node
Example:
node.get_depth()
- get_ancestors()¶
- Returns
A queryset containing the current node object’s ancestors, starting by the root node and descending to the parent. (some subclasses may return a list)
Example:
node.get_ancestors()
- get_children()¶
- Returns
A queryset of all the node’s children
Example:
node.get_children()
- get_children_count()¶
- Returns
The number of the node’s children
Example:
node.get_children_count()
- get_descendants()¶
- Returns
A queryset of all the node’s descendants, doesn’t include the node itself (some subclasses may return a list).
Example:
node.get_descendants()
- get_descendant_count()¶
- Returns
the number of descendants of a node.
Example:
node.get_descendant_count()
- get_first_child()¶
- Returns
The leftmost node’s child, or None if it has no children.
Example:
node.get_first_child()
- get_last_child()¶
- Returns
The rightmost node’s child, or None if it has no children.
Example:
node.get_last_child()
- get_first_sibling()¶
- Returns
The leftmost node’s sibling, can return the node itself if it was the leftmost sibling.
Example:
node.get_first_sibling()
- get_last_sibling()¶
- Returns
The rightmost node’s sibling, can return the node itself if it was the rightmost sibling.
Example:
node.get_last_sibling()
- get_prev_sibling()¶
- Returns
The previous node’s sibling, or None if it was the leftmost sibling.
Example:
node.get_prev_sibling()
- get_next_sibling()¶
- Returns
The next node’s sibling, or None if it was the rightmost sibling.
Example:
node.get_next_sibling()
- get_parent(update=False)¶
- Returns
the parent node of the current node object. Caches the result in the object itself to help in loops.
- Parameters
update – Updates the cached value.
Example:
node.get_parent()
- get_root()¶
- Returns
the root node for the current node object.
Example:
node.get_root()
- get_siblings()¶
- Returns
A queryset of all the node’s siblings, including the node itself.
Example:
node.get_siblings()
- is_child_of(node)¶
- Returns
True
if the node is a child of another node given as an argument, else, returnsFalse
- Parameters
node – The node that will be checked as a parent
Example:
node.is_child_of(node2)
- is_descendant_of(node)¶
- Returns
True
if the node is a descendant of another node given as an argument, else, returnsFalse
- Parameters
node – The node that will be checked as an ancestor
Example:
node.is_descendant_of(node2)
- is_sibling_of(node)¶
- Returns
True
if the node is a sibling of another node given as an argument, else, returnsFalse
- Parameters
node – The node that will be checked as a sibling
Example:
node.is_sibling_of(node2)
- is_root()¶
- Returns
True if the node is a root node (else, returns False)
Example:
node.is_root()
- is_leaf()¶
- Returns
True if the node is a leaf node (else, returns False)
Example:
node.is_leaf()
- move(target, pos=None)¶
Moves the current node and all it’s descendants to a new position relative to another node.
- Parameters
target – The node that will be used as a relative child/sibling when moving
pos –
The position, relative to the target node, where the current node object will be moved to, can be one of:
first-child
: the node will be the new leftmost child of thetarget
nodelast-child
: the node will be the new rightmost child of thetarget
nodesorted-child
: the new node will be moved as a child of thetarget
node according to the value ofnode_order_by
first-sibling
: the node will be the new leftmost sibling of thetarget
nodeleft
: the node will take thetarget
node’s place, which will be moved to the right 1 positionright
: the node will be moved to the right of thetarget
nodelast-sibling
: the node will be the new rightmost sibling of thetarget
nodesorted-sibling
: the new node will be moved as a sibling of thetarget
node according to the value ofnode_order_by
Note
If no
pos
is given the library will uselast-sibling
, orsorted-sibling
ifnode_order_by
is enabled.
- Returns
None
- Raises
InvalidPosition – when passing an invalid
pos
parmInvalidPosition – when
node_order_by
is enabled and thepos
parm wasn’tsorted-sibling
orsorted-child
InvalidMoveToDescendant – when trying to move a node to one of it’s own descendants
PathOverflow – when the library can’t make room for the node’s new position
MissingNodeOrderBy – when passing
sorted-sibling
orsorted-child
aspos
and thenode_order_by
attribute is missing
Note
The node can be moved under another root node.
Examples:
node.move(node2, 'sorted-child') node.move(node2, 'prev-sibling')
- save(force_insert=False, force_update=False, using=None, update_fields=None)¶
Save the current instance. Override this in a subclass if you want to control the saving process.
The ‘force_insert’ and ‘force_update’ parameters can be used to insist that the “save” must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.
- classmethod get_first_root_node()¶
- Returns
The first root node in the tree or
None
if it is empty.
Example:
MyNodeModel.get_first_root_node()
- classmethod get_last_root_node()¶
- Returns
The last root node in the tree or
None
if it is empty.
Example:
MyNodeModel.get_last_root_node()
- classmethod get_root_nodes()¶
- Returns
A queryset containing the root nodes in the tree.
Example:
MyNodeModel.get_root_nodes()
- classmethod load_bulk(bulk_data, parent=None, keep_ids=False)¶
Loads a list/dictionary structure to the tree.
- Parameters
bulk_data –
The data that will be loaded, the structure is a list of dictionaries with 2 keys:
data
: will store arguments that will be passed for object creation, andchildren
: a list of dictionaries, each one has it’s owndata
andchildren
keys (a recursive structure)
parent – The node that will receive the structure as children, if not specified the first level of the structure will be loaded as root nodes
keep_ids – If enabled, loads the nodes with the same id that are given in the structure. Will error if there are nodes without id info or if the ids are already used.
- Returns
A list of the added node ids.
Note
Any internal data that you may have stored in your nodes’ data (
path
,depth
) will be ignored.Note
If your node model has a ForeignKey this method will try to load the related object before loading the data. If the related object doesn’t exist it won’t load anything and will raise a DoesNotExist exception. This is done because the dump_data method uses integers to dump related objects.
Note
If your node model has
node_order_by
enabled, it will take precedence over the order in the structure.Example:
data = [{'data':{'desc':'1'}}, {'data':{'desc':'2'}, 'children':[ {'data':{'desc':'21'}}, {'data':{'desc':'22'}}, {'data':{'desc':'23'}, 'children':[ {'data':{'desc':'231'}}, ]}, {'data':{'desc':'24'}}, ]}, {'data':{'desc':'3'}}, {'data':{'desc':'4'}, 'children':[ {'data':{'desc':'41'}}, ]}, ] # parent = None MyNodeModel.load_bulk(data, None)
Will create:
- classmethod dump_bulk(parent=None, keep_ids=True)¶
Dumps a tree branch to a python data structure.
- Parameters
parent – The node whose descendants will be dumped. The node itself will be included in the dump. If not given, the entire tree will be dumped.
keep_ids – Stores the id value (primary key) of every node. Enabled by default.
- Returns
A python data structure, described with detail in
load_bulk()
Example:
tree = MyNodeModel.dump_bulk() branch = MyNodeModel.dump_bulk(node_obj)
- classmethod find_problems()¶
Checks for problems in the tree structure.
- classmethod fix_tree()¶
Solves problems that can appear when transactions are not used and a piece of code breaks, leaving the tree in an inconsistent state.
- classmethod get_descendants_group_count(parent=None)¶
Helper for a very common case: get a group of siblings and the number of descendants (not only children) in every sibling.
- Parameters
parent – The parent of the siblings to return. If no parent is given, the root nodes will be returned.
- Returns
A list (NOT a Queryset) of node objects with an extra attribute: descendants_count.
Example:
# get a list of the root nodes root_nodes = MyModel.get_descendants_group_count() for node in root_nodes: print '%s by %s (%d replies)' % (node.comment, node.author, node.descendants_count)
- classmethod get_annotated_list(parent=None, max_depth=None)¶
Gets an annotated list from a tree branch.
- Parameters
parent – The node whose descendants will be annotated. The node itself will be included in the list. If not given, the entire tree will be annotated.
max_depth – Optionally limit to specified depth
Example:
annotated_list = MyModel.get_annotated_list()
With data:
Will return:
[ (a, {'open':True, 'close':[], 'level': 0}) (ab, {'open':True, 'close':[], 'level': 1}) (aba, {'open':True, 'close':[], 'level': 2}) (abb, {'open':False, 'close':[], 'level': 2}) (abc, {'open':False, 'close':[0,1], 'level': 2}) (ac, {'open':False, 'close':[0], 'level': 1}) ]
This can be used with a template like:
{% for item, info in annotated_list %} {% if info.open %} <ul><li> {% else %} </li><li> {% endif %} {{ item }} {% for close in info.close %} </li></ul> {% endfor %} {% endfor %}
Note
This method was contributed originally by Alexey Kinyov, using an idea borrowed from django-mptt.
New in version 1.55.
- classmethod get_annotated_list_qs(qs)¶
Gets an annotated list from a queryset.
- classmethod get_database_vendor(action)¶
returns the supported database vendor used by a treebeard model when performing read (select) or write (update, insert, delete) operations.
- Parameters
action – read or write
- Returns
postgresql, mysql or sqlite
Example:
MyNodeModel.get_database_vendor("write")
New in version 1.61.