我正在使用Ben Firshman的fork django-MPTT(Daniel Roseman的recommendation)。
我试图重新订购共享一个共同父节点的节点。我有一个主键列表,如下所示:
ids = [5, 9, 7, 3]
所有这些节点都有一个父节点,比如主键1。
目前,这些节点已订购[5, 3, 9, 7]
,如何将其重新排序为[5, 9, 7, 3]
?
我尝试过这样的事情:
last_m = MyModel.get(pk = ids.pop(0))
last_m.move_to(last_m.parent, position='first-child')
for id in ids:
m = MyModel.get(pk = id)
m.move_to(last_m, position='right')
根据docs on move_to
,我希望按照我的要求行事,但似乎没有任何改变。有时它似乎将ids
中的第一个项目移动为其父项的第一个项目,有时它不会。
我是否正确阅读move_to
在move_to
节点n
上调用position=right
并且目标是{{1}的兄弟会将n
移到目标后面吗?
我可能已经搞砸了我的模型表,试图解决这个问题,所以上面的代码可能是正确的。也有可能有一种更优雅的方式(可能不会涉及n
选择和O(n)
更新)。
我误解了什么吗?
奖金问题:有没有办法强制django-MPTT为给定模型的所有实例重建O(n)
和lft
值?
答案 0 :(得分:5)
我认为这是我之前提到的MPTT失败的假象 - 当您移动节点时,它会正确更新您正在移动的节点的实例,但它不会更新实例target(虽然它确实在数据库中更新)。
这样做的结果是,在您的代码中,每个m
都会移到last_m
的右侧 - 但last_m
中的值仍会反映移动前的位置,因此下一步使用原始的lft / right值而不是新的post-move值。
解决方案是每次重新加载last_m
:
for id in ids:
last_m = MyModel.objects.get(pk=last_m.id)
m = MyModel.get(pk = id)
m.move_to(last_m, position='right')