使用 django-mptt 制作 FeinCMS 页面树的副本更改子顺序

发布于 2024-09-26 07:09:28 字数 1023 浏览 1 评论 0原文

我正在尝试制作 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/managers.py/ 中_inter_tree_move_and_close_gap(),由于某种原因,孙子的“lft”值发生了变化。移动前它们是C=3,D=5,移动后它们是C=5,D=3。

这解释了为什么 D 在 C 之前排序,但我不知道为什么这些值会被切换。有什么想法吗?

I'm trying to make a copy of a FeinCMS page tree, which is managed using django-mptt. I wrote this function:

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)

and call it using

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

It works in general but when I have a page tree looking like this:

A
|- B
   |- C
   |- D

It comes out as this:

A
|- B
   |- D
   |- C

From my stepping through the mptt code, the magic seems to happen in mptt/managers.py/_inter_tree_move_and_close_gap(), where for some reason the "lft" values of the grandchildren get changed. Before the move they are C=3, D=5, afterwards they are C=5, D=3.

Which explains why D gets sorted before C but I have no idea why these values get switched. Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

姐不稀罕 2024-10-03 07:09:28

好吧,我知道一旦我问了 - 我会自己找到答案(之前花了几个小时......)当然,这与 StackOverflow 上所有其他 django-mptt 问题是同样的问题:你必须重新读取对象从数据库中。

我在上面的代码片段中这样做了,但在错误的地方。这是有效的代码(在进入递归函数时重新读取父级):

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)

Ok, I knew once I ask - I'd find the answer myself (after spending hours before...) Of course it's the same problem as in all the other django-mptt problems on StackOverflow: you have to re-read the object from the database.

I did so in the snippet above but at the wrong places. This is the code that works (re-reading the parent on entering the recursive function):

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文