Faire une copie d'un arbre de la page à l'aide FeinCMS django-MPTT change pour des enfants
-
28-09-2019 - |
Question
Je suis en train de faire une copie d'un arbre de la page FeinCMS, qui gère au moyen django-MPTT. J'ai écrit cette fonction:
def make_tree_copy(page, parent=None):
'''
Makes a copy of the tree starting at "page", reparenting it to "parent"
'''
new_page = Page.objects.create_copy(page)
new_page.save()
Page.tree.move_node(new_page, parent)
# re-read so django-mptt fields get updated
new_page = Page.objects.get(id=new_page.id)
for child in page.get_children():
# re-read so django-mptt fields get updated
child = Page.objects.get(id=child.id)
make_tree_copy(child, new_page)
et l'appeler à l'aide
make_tree_copy(Page.tree.root_nodes()[0])
Il fonctionne en général, mais quand j'ai un arbre de la page qui ressemble à ceci:
A
|- B
|- C
|- D
Il est comme ceci:
A
|- B
|- D
|- C
De mon Parcourant le code MPTT, la magie semble se produire dans MPTT / managers.py / _inter_tree_move_and_close_gap (), où pour une raison quelconque les valeurs « LFT » des petits-enfants sont changés. Avant le déménagement, ils sont C = 3, D = 5, ils sont ensuite C = 5, D = 3.
Ce qui explique pourquoi D obtient triés avant C, mais je ne sais pas pourquoi ces valeurs se commutées. Toute pensée?
La solution
Ok, je savais une fois que je demande - je trouve la réponse moi-même (après avoir passé des heures avant ...) Bien sûr, il est le même problème que dans tous les autres problèmes django-MPTT sur StackOverflow: vous devez re- lire l'objet à partir de la base de données.
Je l'ai fait dans l'extrait ci-dessus, mais au mauvais endroit. Ceci est le code qui fonctionne (re-lecture de la mère à l'entrée de la fonction récursive):
def make_tree_copy(page, parent=None):
'''
Makes a copy of the tree starting at "page", reparenting it to "parent"
'''
if parent:
# re-read so django-mptt fields get updated
parent = Page.objects.get(id=parent.id)
new_page = Page.objects.create_copy(page)
new_page.save()
Page.tree.move_node(new_page, parent)
for child in page.get_children():
make_tree_copy(child, new_page)