2012-09-29 22 views
5

Sto sviluppando un progetto che utilizza django-mptt, ma ottengo risultati strani quando utilizzo la funzione get_ancestors. Ecco un esempio.
Ho un creato un modello semplice, ereditato da MPTTModel:Risultati errati quando si usano le funzioni `get_ancestors` da` 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 

E qui è la funzione che funziona con questo modello:

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) 

mi aspettavo di vedere i valori prossimi sull'uscita:

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

Ma invece vedo:

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

Quindi, come vedete questa funzione stampa corretta lista di antenati per bbb nodo, ma antenati sbagliato per aaa nodo. Puoi spiegarmi perché succede? Si tratta di un bug in django-mptt o il mio codice non è corretto?

Grazie in anticipo.

risposta

4

Quando si inserisce un nodo in un albero, si verificano cambiamenti in un intero albero. Quindi, quando inserisci il nodo b, i tuoi nodi a e root cambiano nel database, ma le tue variabili non vengono aggiornate e rimangono per contenere i vecchi valori left/right, che sono usati per costruire la struttura ad albero corretta.

Nel tuo caso, quando la linea è in aa.insert_at(a, save = True) proccess, la variabile a contiene un vecchio un'istanza con lft = 2 e rght = 3, mentre nel database a nodo contiene lft = 4 e rght = 5.

È è necessario ottenere una nuova istanza di un genitore prima di inserire un nuovo elemento. Il modo più semplice per eseguire questa operazione è eseguire refresh_from_db:

aa.refresh_from_db()