使用 django-mptt 制作 FeinCMS 页面树的副本更改子顺序
我正在尝试制作 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我知道一旦我问了 - 我会自己找到答案(之前花了几个小时......)当然,这与 StackOverflow 上所有其他 django-mptt 问题是同样的问题:你必须重新读取对象从数据库中。
我在上面的代码片段中这样做了,但在错误的地方。这是有效的代码(在进入递归函数时重新读取父级):
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):