나중에 참조 할 수 있도록 ...
objects.rebuild()는 특별한 경우에만 필요합니다. 일반적으로 mptt는 노드의 부모 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
Django-mptt를 이해하는 한, 트리에 노드를 추가 한 후 항상 트리를 다시 빌드해야합니다. node.parent = parent, node.save(). TreeNodes.objects.rebuild()를 따라야합니다. 명령. –
이후 작업을 다시 수행하지 않고 작업 결과를 테스트 했습니까? 나는 이것이 전혀 필요하지 않다는 것을 감히 말한다. TreeManager 구현을 살펴보십시오. –