在Django-MPTT中重新排序子节点 [英] Re-ordering child nodes in django-MPTT

查看:94
本文介绍了在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为给定模型的所有实例重建lftrght值?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆