5

django-mpttを使用するプロジェクトを開発していますが、get_ancestors関数を使用すると奇妙な結果が得られます。これが例です。
MPTTModelから継承した単純なモデルを作成しました。

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

そして、これがこのモデルで動作する関数です:

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)

出力に次の値が表示されることを期待していました。

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

しかし、私が見ると主張しました:

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

ご覧のとおり、この関数はノードの祖先の正しいリストを出力しますbbbが、ノードの祖先は間違っていaaaます。なぜこれが起こるのか説明してもらえますか?これはバグですか、django-mpttそれとも私のコードは正しくありませんか?

前もって感謝します。

4

2 に答える 2

5

ノードをツリーに挿入すると、ツリー全体に変更が加えられます。したがって、bノードを挿入するaroot、データベースでノードが変更されますが、変数は更新されず、正しいツリー構造を構築するために使用される古い左/右の値が含まれたままになります。

あなたの場合、行aa.insert_at(a, save = True)が処理中のとき、変数には=2と=3aの古いインスタンスが含まれ、データベースノードには=4と=5が含まれます。lftrghtalftrght

新しいアイテムを挿入する前に、親の新しいインスタンスを取得する必要があります。これを行う最も簡単な方法は、以下を実行することrefresh_from_dbです。

aa.refresh_from_db()
于 2012-09-29T18:36:56.413 に答える
0

セルゲイの答えに同意します。ツリーを再構築するために使用するコマンドは次のとおりです。

ModelName.objects.rebuild()   

(「pythonmanage.pyシェル」で実行)

于 2021-02-01T16:30:22.503 に答える