mptt.models
¶
-
class
mptt.models.
TreeForeignKey
(to, on_delete, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, to_field=None, db_constraint=True, **kwargs)¶ Extends the foreign key, but uses mptt’s
TreeNodeChoiceField
as the default form field.This is useful if you are creating models that need automatically generated ModelForms to use the correct widgets.
-
formfield
(**kwargs)¶ Use MPTT’s
TreeNodeChoiceField
-
-
class
mptt.models.
TreeOneToOneField
(to, on_delete, to_field=None, **kwargs)¶ -
formfield
(**kwargs)¶ Pass
limit_choices_to
to the field being constructed.Only passes it if there is a type that supports related fields. This is a similar strategy used to pass the
queryset
to the field being constructed.
-
-
class
mptt.models.
TreeManyToManyField
(to, related_name=None, related_query_name=None, limit_choices_to=None, symmetrical=None, through=None, through_fields=None, db_constraint=True, db_table=None, swappable=True, **kwargs)¶ -
formfield
(**kwargs)¶ Pass
limit_choices_to
to the field being constructed.Only passes it if there is a type that supports related fields. This is a similar strategy used to pass the
queryset
to the field being constructed.
-
-
class
mptt.models.
TreeManager
¶ A manager for working with trees of objects.
Adds a related item count to a given
QuerySet
using itsextra
method, for aModel
class which has a relation to thisManager
’sModel
class.Arguments:
rel_model
- A
Model
class which has a relation to this Manager`’sModel
class. rel_field
- The name of the field in
rel_model
which holds the relation. count_attr
- The name of an attribute which should be added to each item in
this
QuerySet
, containing a count of how many instances ofrel_model
are related to it throughrel_field
. cumulative
- If
True
, the count will be for each item and all of its descendants, otherwise it will be for each item itself. extra_filters
- Dict with aditional parameters filtering the related queryset.
-
build_tree_nodes
(data, target=None, position='last-child')¶ Load a tree from a nested dictionary for bulk insert, returning an array of records. Use to efficiently insert many nodes within a tree without an expensive rebuild.
records = MyModel.objects.build_tree_nodes({ 'id': 7, 'name': 'parent', 'children': [ { 'id': 8, 'parent_id': 7, 'name': 'child', 'children': [ { 'id': 9, 'parent_id': 8, 'name': 'grandchild', } ] } ] }) MyModel.objects.bulk_create(records)
-
contribute_to_class
(model, name)¶
-
delay_mptt_updates
()¶ Context manager. Delays mptt updates until the end of a block of bulk processing.
NOTE that this context manager causes inconsistencies! MPTT model methods are not guaranteed to return the correct results until the end of the context block.
- When to use this method:
If used correctly, this method can be used to speed up bulk updates. This is best for updates in a localised area of the db table, especially if all the updates happen in a single tree and the rest of the forest is left untouched. No subsequent rebuild is necessary.
delay_mptt_updates
does a partial rebuild of the modified trees (not the whole table). If used indiscriminately, this can actually be much slower than just letting the updates occur when they’re required.The worst case occurs when every tree in the table is modified just once. That results in a full rebuild of the table, which can be very slow.
If your updates will modify most of the trees in the table (not a small number of trees), you should consider using
TreeManager.disable_mptt_updates
, as it does much fewer queries.- Transactions:
- This doesn’t enforce any transactional behavior. You should wrap this in a transaction to ensure database consistency.
- Exceptions:
- If an exception occurs before the processing of the block, delayed updates will not be applied.
Usage:
with transaction.atomic(): with MyNode.objects.delay_mptt_updates(): ## bulk updates.
-
disable_mptt_updates
()¶ Context manager. Disables mptt updates.
NOTE that this context manager causes inconsistencies! MPTT model methods are not guaranteed to return the correct results.
- When to use this method:
If used correctly, this method can be used to speed up bulk updates.
This doesn’t do anything clever. It will mess up your tree. You should follow this method with a call to
TreeManager.rebuild()
to ensure your tree stays sane, and you should wrap both calls in a transaction.This is best for updates that span a large part of the table. If you are doing localised changes (one tree, or a few trees) consider using
delay_mptt_updates
.If you are making only minor changes to your tree, just let the updates happen.
- Transactions:
- This doesn’t enforce any transactional behavior. You should wrap this in a transaction to ensure database consistency.
If updates are already disabled on the model, this is a noop.
Usage:
with transaction.atomic(): with MyNode.objects.disable_mptt_updates(): ## bulk updates. MyNode.objects.rebuild()
-
get_queryset
(*args, **kwargs)¶ Ensures that this manager always returns nodes in tree order.
-
get_queryset_ancestors
(queryset, include_self=False)¶ Returns a queryset containing the ancestors of all nodes in the given queryset.
If
include_self=True
, nodes inqueryset
will also be included in the result.
-
get_queryset_descendants
(queryset, include_self=False)¶ Returns a queryset containing the descendants of all nodes in the given queryset.
If
include_self=True
, nodes inqueryset
will also be included in the result.
-
insert_node
(node, target, position='last-child', save=False, allow_existing_pk=False, refresh_target=True)¶ Sets up the tree state for
node
(which has not yet been inserted into in the database) so it will be positioned relative to a giventarget
node as specified byposition
(when appropriate) it is inserted, with any necessary space already having been made for it.A
target
ofNone
indicates thatnode
should be the last root node.If
save
isTrue
,node
’ssave()
method will be called before it is returned.NOTE: This is a low-level method; it does NOT respect
MPTTMeta.order_insertion_by
. In most cases you should just set the node’s parent and let mptt call this during save.
-
left_attr
¶
-
level_attr
¶
-
move_node
(node, target, position='last-child')¶ Moves
node
relative to a giventarget
node as specified byposition
(when appropriate), by examining both nodes and calling the appropriate method to perform the move.A
target
ofNone
indicates thatnode
should be turned into a root node.Valid values for
position
are'first-child'
,'last-child'
,'left'
or'right'
.node
will be modified to reflect its new tree state in the database.This method explicitly checks for
node
being made a sibling of a root node, as this is a special case due to our use of tree ids to order root nodes.NOTE: This is a low-level method; it does NOT respect
MPTTMeta.order_insertion_by
. In most cases you should just move the node yourself by setting node.parent.
-
parent_attr
¶
-
partial_rebuild
(tree_id, batch_size=1000, **filters)¶ Partially rebuilds a tree i.e. It rebuilds only the tree with given
tree_id
in database table usingparent
link.
-
rebuild
(batch_size=1000, **filters) → None¶ Rebuilds all trees in the database table using parent link.
-
right_attr
¶
-
root_node
(tree_id)¶ Returns the root node of the tree with the given id.
-
root_nodes
()¶ Creates a
QuerySet
containing root nodes.
-
tree_id_attr
¶
-
class
mptt.models.
MPTTOptions
(opts=None, **kwargs)¶ Options class for MPTT models. Use this as an inner class called
MPTTMeta
:class MyModel(MPTTModel): class MPTTMeta: order_insertion_by = ['name'] parent_attr = 'myparent'
-
get_ordered_insertion_target
(node, parent)¶ Attempts to retrieve a suitable right sibling for
node
underneathparent
(which may beNone
in the case of root nodes) so that ordering by the fields specified by the node’s class’order_insertion_by
option is maintained.Returns
None
if no suitable sibling can be found.
-
get_raw_field_value
(instance, field_name)¶ Gets the value of the given fieldname for the instance. This is not the same as getattr(). This function will return IDs for foreignkeys etc, rather than doing a database query.
-
insertion_target_filters
(instance, order_insertion_by)¶ Creates a filter which matches suitable right siblings for
node
, where insertion should maintain ordering according to the list of fields inorder_insertion_by
.For example, given an
order_insertion_by
of['field1', 'field2', 'field3']
, the resulting filter should correspond to the following SQL:field1 > %s OR (field1 = %s AND field2 > %s) OR (field1 = %s AND field2 = %s AND field3 > %s)
-
left_attr
= 'lft'¶
-
level_attr
= 'level'¶
-
order_insertion_by
= []¶
-
parent_attr
= 'parent'¶
-
right_attr
= 'rght'¶
-
set_raw_field_value
(instance, field_name, value)¶ Sets the value of the given fieldname for the instance. This is not the same as setattr(). This function requires an ID for a foreignkey (etc) rather than an instance.
-
tree_id_attr
= 'tree_id'¶
-
update_mptt_cached_fields
(instance)¶ - Caches (in an instance._mptt_cached_fields dict) the original values of:
- parent pk
- fields specified in order_insertion_by
These are used in save() to determine if the relevant fields have changed, so that the MPTT fields need to be updated.
-
-
class
mptt.models.
MPTTModelBase
¶ Metaclass for MPTT models
-
classmethod
register
(cls, **kwargs)¶ For the weird cases when you need to add tree-ness to an existing class. For other cases you should subclass MPTTModel instead of calling this.
-
classmethod
-
class
mptt.models.
MPTTModel
(*args, **kwargs)¶ Base class for tree models.
-
delete
(*args, **kwargs)¶ Calling
delete
on a node will delete it as well as its full subtree, as opposed to reattaching all the subnodes to its parent node.There are no argument specific to a MPTT model, all the arguments will be passed directly to the django’s
Model.delete
.delete
will not return anything.
-
get_ancestors
(ascending=False, include_self=False)¶ Creates a
QuerySet
containing the ancestors of this model instance.This defaults to being in descending order (root ancestor first, immediate parent last); passing
True
for theascending
argument will reverse the ordering (immediate parent first, root ancestor last).If
include_self
isTrue
, theQuerySet
will also include this model instance.
-
get_children
()¶ Returns a
QuerySet
containing the immediate children of this model instance, in tree order.The benefit of using this method over the reverse relation provided by the ORM to the instance’s children is that a database query can be avoided in the case where the instance is a leaf node (it has no children).
If called from a template where the tree has been walked by the
cache_tree_children
filter, no database query is required.
-
get_descendant_count
()¶ Returns the number of descendants this model instance has.
-
get_descendants
(include_self=False)¶ Creates a
QuerySet
containing descendants of this model instance, in tree order.If
include_self
isTrue
, theQuerySet
will also include this model instance.
-
get_family
()¶ Returns a
QuerySet
containing the ancestors, the model itself and the descendants, in tree order.
-
get_leafnodes
(include_self=False)¶ Creates a
QuerySet
containing leafnodes of this model instance, in tree order.If
include_self
isTrue
, theQuerySet
will also include this model instance (if it is a leaf node)
-
get_level
()¶ Returns the level of this node (distance from root)
-
get_next_sibling
(*filter_args, **filter_kwargs)¶ Returns this model instance’s next sibling in the tree, or
None
if it doesn’t have a next sibling.
-
get_previous_sibling
(*filter_args, **filter_kwargs)¶ Returns this model instance’s previous sibling in the tree, or
None
if it doesn’t have a previous sibling.
-
get_root
()¶ Returns the root node of this model instance’s tree.
-
get_siblings
(include_self=False)¶ Creates a
QuerySet
containing siblings of this model instance. Root nodes are considered to be siblings of other root nodes.If
include_self
isTrue
, theQuerySet
will also include this model instance.
-
insert_at
(target, position='first-child', save=False, allow_existing_pk=False, refresh_target=True)¶ Convenience method for calling
TreeManager.insert_node
with this model instance.
-
is_ancestor_of
(other, include_self=False)¶ Returns
True
if this model is an ancestor of the given node,False
otherwise. If include_self is True, also returns True if the two nodes are the same node.
-
is_child_node
()¶ Returns
True
if this model instance is a child node,False
otherwise.
-
is_descendant_of
(other, include_self=False)¶ Returns
True
if this model is a descendant of the given node,False
otherwise. If include_self is True, also returns True if the two nodes are the same node.
-
is_leaf_node
()¶ Returns
True
if this model instance is a leaf node (it has no children),False
otherwise.
-
is_root_node
()¶ Returns
True
if this model instance is a root node,False
otherwise.
-
move_to
(target, position='first-child')¶ Convenience method for calling
TreeManager.move_node
with this model instance.NOTE: This is a low-level method; it does NOT respect
MPTTMeta.order_insertion_by
. In most cases you should just move the node yourself by setting node.parent.
-
objects
¶
-
save
(*args, **kwargs)¶ If this is a new node, sets tree fields up before it is inserted into the database, making room in the tree structure as necessary, defaulting to making the new node the last child of its parent.
It the node’s left and right edge indicators already been set, we take this as indication that the node has already been set up for insertion, so its tree fields are left untouched.
If this is an existing node and its parent has been changed, performs reparenting in the tree structure, defaulting to making the node the last child of its new parent.
In either case, if the node’s class has its
order_insertion_by
tree option set, the node will be inserted or moved to the appropriate position to maintain ordering by the specified field.
-