2012-09-29 11 views
5

Ich entwickle ein Projekt, das django-mptt verwendet, aber ich bekomme seltsame Ergebnisse, wenn ich get_ancestors Funktion verwende. Hier ist ein Beispiel.
Ich habe ein ein einfaches Modell erstellt, von MPTTModel geerbt:Falsche Ergebnisse, wenn `get_ancestors` Funktionen von` django-mptt` verwenden

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 

Und hier ist die Funktion, die mit diesem Modell funktioniert:

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) 

I nächste Werte auf dem Ausgang sehen erwartet:

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

Aber insted ich sehe:

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

So wie Sie sehen, druckt diese Funktion korrekte Liste der Vorfahren für bbb Knoten, aber falsche Vorfahren für aaa Knoten. Kannst du mir erklären, warum das passiert? Ist das ein Fehler in oder ist mein Code falsch?

Vielen Dank im Voraus.

Antwort

4

Wenn Sie einen Knoten in einen Baum einfügen, verursacht dies Änderungen in einem ganzen Baum. Wenn Sie also den Knoten b einfügen, ändern sich Ihre Knoten a und root in der Datenbank, aber Ihre Variablen werden nicht aktualisiert und enthalten weiterhin alte Links/Rechts-Werte, die zum Erstellen der korrekten Baumstruktur verwendet werden.

In Ihrem Fall, wenn die Leitung aa.insert_at(a, save = True) in proccess ist, Ihre a Variable enthält eine alte Instanz mit lft = 2 und rght = 3, während in der Datenbank a Knoten lft enthält = 4 und rght = 5.

Sie müssen vor dem Einfügen eines neuen Elements eine neue Instanz eines übergeordneten Elements abrufen. Der einfachste Weg dazu ist refresh_from_db:

aa.refresh_from_db()