2012-09-29 16 views
5

Estoy desarrollando un proyecto que usa django-mptt, pero obtengo resultados extraños cuando uso la función get_ancestors. Aquí hay un ejemplo.
Tengo un creado un modelo simple, heredado de MPTTModel:Resultados incorrectos cuando uso las funciones `get_ancestors` de` django-mptt`

class Classifier(MPTTModel): 
    title = models.CharField(max_length=255) 
    parent = TreeForeignKey('self', null = True, blank = True, 
          related_name = 'children') 

    def __unicode__(self): 
     return self.title 

Y aquí es la función que trabaja con este modelo:

def test_mptt(self): 
    # Erase all data from table 
    Classifier.objects.all().delete() 

    # Create a tree root 
    root, created = Classifier.objects.get_or_create(title=u'root', parent=None) 

    # Create 'a' and 'b' nodes whose parent is 'root' 
    a = Classifier(title = "a") 
    a.insert_at(root, save = True) 
    b = Classifier(title = "b") 
    b.insert_at(root, save = True) 

    # Create 'aa' and 'bb' nodes whose parents are 
    # 'a' and 'b' respectively 
    aa = Classifier(title = "aa") 
    aa.insert_at(a, save = True) 
    bb = Classifier(title = "bb") 
    bb.insert_at(b, save = True) 

    # Create two more nodes whose parents are 'aa' and 'bb' respectively 
    aaa = Classifier(title = "aaa") 
    aaa.insert_at(aa, save = True) 
    bba = Classifier(title = "bbb") 
    bba.insert_at(bb, save = True) 

    # Select from table just created nodes 
    first = Classifier.objects.get(title = "aaa") 
    second = Classifier.objects.get(title = "bbb") 

    # Print lists of selected nodes' ancestors: 
    print first.get_ancestors(ascending=True, include_self=True) 
    print second.get_ancestors(ascending=True, include_self=True) 

esperaba ver siguientes valores en la salida:

[<Classifier: aaa>, <Classifier: aa>, <Classifier: a>, <Classifier: root>] 
[<Classifier: bbb>, <Classifier: bb>, <Classifier: b>, <Classifier: root>] 

Pero insted veo:

[<Classifier: aaa>, <Classifier: bb>, <Classifier: b>, <Classifier: root>] 
[<Classifier: bbb>, <Classifier: bb>, <Classifier: b>, <Classifier: root>] 

Como ve esta función imprime la lista correcta de ancestros para el nodo bbb, pero ancestros incorrectos para el nodo aaa. ¿Puedes explicarme por qué sucede esto? ¿Es esto un error en django-mptt o mi código es incorrecto?

Gracias de antemano.

Respuesta

4

Cuando inserta un nodo en un árbol, produce un cambio en un árbol completo. Por lo tanto, cuando inserta el nodo b, sus nodos a y root cambian en la base de datos, pero sus variables no se actualizan y permanecen para contener los valores antiguos a la izquierda/derecha, que se utilizan para construir la estructura de árbol correcta.

En su caso, cuando la línea aa.insert_at(a, save = True) está en proccess, su variable de a contiene una instancia antigua con lft = 2 y rght = 3, mientras que en la base de datos a nodo contiene lft = 4 y rght = 5.

Usted Necesita obtener una nueva instancia de un padre antes de insertar un nuevo elemento. La forma más fácil de hacerlo es ejecutar refresh_from_db:

aa.refresh_from_db() 
Cuestiones relacionadas