在django-MPTT中重新排序子节点

时间:2010-02-24 09:00:54

标签: django django-mptt

我正在使用Ben Firshman的fork django-MPTT(Daniel Rosemanrecommendation)。

我试图重新订购共享一个共同父节点的节点。我有一个主键列表,如下所示:

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_tomove_to节点n上调用position=right并且目标是{{1}的兄弟会将n移到目标后面吗?

我可能已经搞砸了我的模型表,试图解决这个问题,所以上面的代码可能是正确的。也有可能有一种更优雅的方式(可能不会涉及n选择和O(n)更新)。

我误解了什么吗?

奖金问题:有没有办法强制django-MPTT为给定模型的所有实例重建O(n)lft值?

1 个答案:

答案 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')