以供將來參考..
objects.rebuild()只需要在某些特殊情況下。通常情況下,只需設置節點的父節點id,就可以正確設置節點的左右值。這也是在docs
中提到我遇到了一個問題,沒有正確設置左,右值,因爲我保存了新的節點!我重置了其他已有的兄弟姐妹的位置值。爲具有元屬性order_insertion_by
集的樹插入新節點時,必須首先重置所有兄弟的order_insertion_by值,然後保存新節點。這樣mptt能夠正確地重新計算左邊的值。
見我(簡化)下面的例子:
models.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']
views.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()
update_node_positions
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)
任何原因,你會重建你的樹定期? – user2298943 2013-05-13 07:08:49
據我瞭解,Django-mptt總是必須在向樹添加節點之後重新生成樹,如下所示:node.parent = parent,node.save(),它必須遵循TreeNodes.objects.rebuild()命令。 – 2013-05-13 07:27:21
您是否測試了操作的結果,而無需任何後續重建?我敢說,這根本不是必要的。看看TreeManager的實現。 – 2013-05-13 16:27:52