2010-02-24 26 views
7

Używam wersji fork firmy Ben Firshman dla django-MPTT (końcówka kapelusza to Daniel Roseman dla recommendation).Ponowna kolejność węzłów potomnych w django-MPTT

Utknąłem, próbując ponownie zamówić węzły, które mają wspólnego rodzica. Mam listę kluczy podstawowych, takich jak to:

ids = [5, 9, 7, 3] 

Wszystkie te węzły mają rodziców, powiedzmy z klucza podstawowego 1.

chwili obecnej węzły te są sortowane [5, 3, 9, 7], jak mogę ponownie zamówić je do [5, 9, 7, 3]?

Próbowałem coś takiego:

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

Które będę oczekiwać, aby robić to, co chcę, za tym docs on move_to, ale nie wydaje się, aby cokolwiek zmienić. Czasami wydaje się, że pierwszy element w ids jest pierwszym dzieckiem swojego rodzica, czasami nie.

mam rację w moim czytaniu docs dla move_tomove_to że dzwoniąc na węźle n z position=right i cel, który jest rodzeństwo n ruszy n natychmiast po cel?

Możliwe, że spieprzyłem tabelę modeli, próbując to rozgryźć, więc może powyższy kod jest w porządku. Możliwe jest też, że jest to o wiele bardziej elegancki sposób (być może taki, który nie wymaga wybrania O(n) i aktualizacji O(n)).

Czy coś źle zrozumiałem?

Pytanie dodatkowe: czy istnieje sposób na zmuszenia django-MPTT do odbudowania wartości lft i rght dla wszystkich wystąpień danego modelu?

Odpowiedz

5

Myślę, że jest to artefakt o niepowodzeniu w MPTT, o którym już wspominałem - kiedy przesuniesz węzły, poprawnie aktualizuje instancję węzła, który się porusza, ale nie aktualizuje instancji cel (mimo że jest aktualizowany w bazie danych).

Konsekwencją tego jest to, że w kodzie, każdy m zostanie przeniesiony na prawo od last_m - ale wartości w last_m nadal odzwierciedlać stanowiska przed przeprowadzką, więc następnym krokiem wykorzystuje oryginalne LFT/wartości w prawo zamiast nowych post-ruchowych.

Rozwiązaniem jest przeładować last_m za każdym razem:

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') 
+0

Podejrzewałem, że to coś z tym zrobić - po przeczytaniu kilku swoich odpowiedziach na pytania MPTT. Dam ci to. Czy masz pojęcie o pytaniu o bonus? –

+0

@Daniel - zapomniałem zamknąć pętlę na tym. Twoja odpowiedź zadziałała świetnie. Wciąż trochę denerwujesz się MPTT i możliwością, że drzewo stanie się w złym stanie - czy masz jakieś wskazówki, jak sobie z tym poradzić? –

+3

Stare pytanie, ale dla każdego, kto się tu potknie - możesz odbudować drzewo MPTT z ModelName.tree.rebuild(). Jest to przydatne, jeśli zdefiniowałeś pole MPTTMeta order_insertion_by i musisz zaktualizować kolejność swojego drzewa. – Nagyman