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]
All of these nodes have a parent, say with primary key 1.
At present, these nodes are ordered [5, 3, 9, 7]
, how can I re-order them to [5, 9, 7, 3]
?
I've tried something like this:
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.
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?
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).
Have I misunderstood something?
Bonus question: is there a way of forcing django-MPTT to rebuild lft
and rght
values for all instances of a given model?
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).
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.
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With