2010-02-24 21 views
7

Estoy usando Ben Firshman's fork de django-MPTT (punta de sombrero Daniel Roseman para recommendation).Reordenando nodos secundarios en django-MPTT

Me he atascado intentando volver a pedir nodos que comparten un elemento primario común. Tengo una lista de claves primarias, así:

ids = [5, 9, 7, 3] 

Todos estos nodos tienen un padre, decir con clave primaria 1.

En la actualidad, estos nodos se ordenan [5, 3, 9, 7], ¿cómo puedo volver a ordenarlos al [5, 9, 7, 3]?

He intentado algo como esto:

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

Qué yo esperaría a hacer lo que quiera, por el docs on move_to, pero no parece que cambiar nada. A veces parece mover el primer elemento en ids para ser el primer hijo de su elemento primario, a veces no lo hace.

Estoy en lo cierto en mi lectura de los documentos para move_to que llamar move_to en un nodo n con position=right y un objetivo que es un hermano de n se moverá a n inmediatamente después de la meta?

Es posible que haya estropeado la mesa de mis modelos al tratar de resolver esto, así que tal vez el código anterior sea realmente correcto. También es posible que haya una forma mucho más elegante de hacerlo (tal vez una que no incluya O(n) selecciones y O(n) actualizaciones).

¿He entendido mal algo?

Pregunta adicional: ¿hay alguna manera de forzar a django-MPTT a reconstruir los valores lft y rght para todas las instancias de un modelo dado?

Respuesta

5

Creo que esto es un artefacto de una falla en MPTT que he mencionado antes: cuando mueve los nodos, actualiza correctamente la instancia del nodo que está moviendo, pero no actualiza la instancia de el objetivo (aunque se actualiza en la base de datos).

La consecuencia de esto es que en su código, cada m será movida a la derecha de last_m - pero los valores en el last_m todavía reflejan la posición antes de la mudanza, por lo que el siguiente movimiento utiliza los valores originales lft/derecha en vez de los nuevos post-movimiento.

La solución es para recargar last_m cada vez:

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

que sospechaba que era algo que ver con que - después de haber leído algunas de sus respuestas a las preguntas MPTT. Voy a dar una oportunidad. ¿Tienes alguna idea sobre la pregunta extra? –

+0

@Daniel: se olvidó de cerrar el ciclo de eso. Tu respuesta funcionó muy bien. Todavía un poco nervioso sobre MPTT y la posibilidad de que el árbol se ponga en mal estado. ¿Tiene algún consejo para gestionarlo? –

+3

Pregunta anterior, pero para cualquiera que tropiece aquí, puede reconstruir un árbol MPTT con ModelName.tree.rebuild(). Esto es útil si ha definido el campo MPTTMeta order_insertion_by y necesita actualizar el orden de su árbol. – Nagyman

Cuestiones relacionadas