Создание копии дерева страниц FeinCMS с использованием django-mptt изменяет дочерний порядок - PullRequest
2 голосов
/ 07 октября 2010

Я пытаюсь сделать копию дерева страниц FeinCMS, которое управляется с помощью django-mptt. Я написал эту функцию:

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)

и позвоните по номеру

make_tree_copy(Page.tree.root_nodes()[0])

В целом это работает, но когда у меня дерево страниц выглядит так:

A
|- B
   |- C
   |- D

Получается так:

A
|- B
   |- D
   |- C

Из моего шага по коду mptt волшебство, похоже, происходит в mptt / Manager.py / _inter_tree_move_and_close_gap (), где по какой-то причине меняются значения lft внуков. Перед ходом они C = 3, D = 5, затем C = 5, D = 3.

Что объясняет, почему D сортируется до C, но я понятия не имею, почему эти значения переключаются. Есть мысли?

1 Ответ

4 голосов
/ 07 октября 2010

Хорошо, я знал однажды, когда спрашиваю - я сам найду ответ (потратив несколько часов до ...) Конечно, это та же проблема, что и во всех других проблемах django-mptt в StackOverflow: вам нужно повторночитать объект из базы данных.

Я сделал это в приведенном выше фрагменте, но в неправильных местах.Вот код, который работает (перечитывая родительский элемент при входе в рекурсивную функцию):

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)
...