备查..
objects.rebuild() 仅在某些特殊情况下才需要。通常 mptt 仅通过设置节点的父 id 来正确设置节点的左右值。文档中也提到了这一点
我遇到了未正确设置左右值的问题,因为我保存了新节点!之前!我重置了其他已经存在的兄弟姐妹的位置值。当为具有元属性order_insertion_by
集的树插入新节点时,必须首先重置所有兄弟节点的 order_insertion_by 值,然后保存新节点。这样 mptt 能够正确地重新计算左右值。
请参阅下面的(简化)示例:
模型.py
class Node(MPTTModel):
"""
Representation of a single node
"""
name = models.CharField(max_length=200)
parent = TreeForeignKey('self', null=True, blank=True, related_name='%(app_label)s_%(class)s_children')
position = models.PositiveIntegerField(max_length=10) #for nodes on the same hierarchy level we have to define the position in which they are displayed
class MPTTMeta:
order_insertion_by = ['position']
视图.py
new_node = Node(name="new node", parent=parent_node, position=1)
update_node_positions(new_node, 1) #routine to update the node positions
new_node.save()
更新节点位置
def update_node_positions(node, mode):
"""
Procedure to update the node positions
Three different modes available:
1 = insert node
2 = update position, parent stays the same
3 = update position and change parent
4 = trashed
"""
if mode == 1 or mode==3:
#if node has been inserted at the beginning
if node.position == 1:
node.get_siblings().update(position=F('position') + 1)
#if node has been inserted not at beginning and not at the last position
elif node.position != node.get_siblings().count() + 1:
#update positions of siblings right of node by one
node.get_siblings().filter(position__gte=node.position).update(position=F('position') + 1)
if mode == 3:
#since we removed the node from a parent, we have to decrement the positions of the former siblings right of the node by one
if node._original_parent is not None:
#do updates only for nodes which had a parent before. will not be executed for root nodes
node._original_parent.get_children().filter(position__gt=node._original_position).update(position=F('position') - 1)
if mode == 2:
#if old position is left of new position -> decrement position by 1 for nodes which have position <= node.position AND > node.original_position
if node.position > node._original_position:
node.get_siblings().filter(Q(position__lte=node.position) & Q(position__gt=node._original_position)).update(position=F('position') - 1)
#if old position is right of new position -> increment position by 1 for nodes which have position >= node.position AND < node.original_position
if node.position < node._original_position:
node.get_siblings().filter(Q(position__gte=node.position) & Q(position__lt=node._original_position)).update(position=F('position') + 1)
if mode == 4:
#decrement position by 1 for nodes which have position > node.position
node.get_siblings().filter(Q(position__gt=node.position)).update(position=F('position') - 1)