在Django-MPTT中重新排序子节点 [英] Re-ordering child nodes in django-MPTT
问题描述
我正在使用django-MPTT的Ben Firshman的 fork (向Daniel Roseman ./south-migrations-mptt/"rel =" nofollow noreferrer>推荐).
I'm using Ben Firshman's fork of django-MPTT (hat tip to Daniel Roseman for the recommendation).
我一直在尝试重新排序共享公共父节点的节点.我有一个主键列表,像这样:
I've got stuck trying to re-order nodes which share a common parent. I've got a list of primary keys, like this:
ids = [5, 9, 7, 3]
所有这些节点都有一个父节点,例如主键为1.
All of these nodes have a parent, say with primary key 1.
目前,这些节点是按[5, 3, 9, 7]
排序的,如何将它们重新排序为[5, 9, 7, 3]
?
At present, these nodes are ordered [5, 3, 9, 7]
, how can I re-order them to [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')
Which I'd expect to do what I want, per the docs on move_to
, but it doesn't seem to change anything. Sometimes it seems to move the first item in ids
to be the first child of its parent, sometimes it doesn't.
我正确地阅读了move_to
的文档时,在具有position=right
的节点n
上调用move_to
且目标为n
的同级对象会将n
移至紧随其后的位置.目标?
Am I right in my reading of the docs for move_to
that calling move_to
on a node n
with position=right
and a target which is a sibling of n
will move n
to immediately after the target?
我可能搞砸了我的模型表以试图解决这个问题,所以上面的代码实际上是正确的.可能还有一种更优雅的方法(也许不涉及O(n)
选择和O(n)
更新).
It's possible I've screwed up my models table in trying to figure this out, so maybe the code above is actually right. It's also possible there's a much more elegant way of doing this (perhaps one that doesn't involve O(n)
selects and O(n)
updates).
我误解了吗?
奖金问题:是否有一种方法可以强制django-MPTT为给定模型的所有实例重建lft
和rght
值?
Bonus question: is there a way of forcing django-MPTT to rebuild lft
and rght
values for all instances of a given model?
推荐答案
我认为这是我之前提到的MPTT失败的伪影-当您移动节点时,它会正确更新您所节点的实例正在移动,但是它不会更新目标实例(尽管它确实已在数据库中更新).
I think this is an artefact of a failure in MPTT that I've mentioned before - when you move nodes around, it correctly updates the instance of the node you're moving, but it doesn't update the instance of the target (although it does get updated in the database).
其结果是,在您的代码中,每个m
都移到了last_m
的右侧-但是last_m
中的值仍然反映了移动之前的位置,因此下一个移动将使用原始位置lft/right值,而不是新的移动后值.
The consequence of this is that in your code, each m
gets moved to the right of last_m
- but the values in the last_m
still reflect the position before the move, so the next move uses the original lft/right values instead of the new post-move ones.
解决方案是每次重新加载last_m
:
The solution is to reload last_m
each time:
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')
这篇关于在Django-MPTT中重新排序子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!