Я использую ветвление Ben Firshman django-MPTT (благодарность за информацию Daniel Roseman для рекомендации).
Я застрял, пытаясь переупорядочить узлы, которые совместно используют общего родителя. У меня есть список первичных ключей, как это:
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')
Который я ожидал бы делать то, о чем я хочу на документы move_to
, но это, кажется, ничего не изменяет. Иногда это, кажется, перемещает первый объект в ids
чтобы быть первым ребенком его родителя, иногда это не делает.
Действительно ли я прав в своем чтении документов для move_to
тот вызов move_to
на узле n
с position=right
и цель, которая является одноуровневым элементом n
переместится n
к сразу после цели?
Возможно, что я завинтил свою таблицу моделей в попытке понять это, поэтому возможно, код выше является на самом деле правильным. Также возможно, что существует намного более изящный способ сделать это (возможно, тот, который не включает O(n)
выбирает и O(n)
обновления).
Я неправильно понял что-то?
Вопрос о премии: есть ли способ вынудить django-MPTT восстановить lft
и rght
значения для всех экземпляров данной модели?
Я думаю, что это артефакт сбоя в MPTT, о котором я упоминал ранее - когда вы перемещаете узлы, он правильно обновляет экземпляр перемещаемого узла, но не обновляет экземпляр target (хотя он обновляется в базе данных).
Следствием этого является то, что в вашем коде каждый m
перемещается вправо от last_m
, но значения в last_m
по-прежнему отражают положение перед перемещением, поэтому при следующем перемещении используются исходные значения lft / right вместо новых значений после перемещения.
Решение состоит в том, чтобы каждый раз перезагружать 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')