7

私は運がほとんどない状態でdjango-mpttを使用しようとしています。これは、Python2.5、windows、sqlite3、Django 1.2pre、svn の最新の django-mptt を使用しています。

コード:

モデル:

class Node(models.Model):
    name   = models.CharField(max_length=20, blank=True)
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children')

    def __unicode__(self):
        return self.name

mptt.register(Node)

設定:

nodes = []
for i in range(15):
    n = Node(name='node'+str(i))
    n.save()
    nodes.append(n)

nodes[0].move_to(None)
nodes[0].save()
for n in range(1,15):
    nodes[n].move_to(nodes[(n-1)/2],'last-child')
    nodes[n].save()

これにより、1 つのルートと 2 つの子が各非リーフ ノードからぶら下がっているツリーが作成されます。

さあ、楽しみが始まります:

>>> nodes[0].children.all()
[<Node: node1>, <Node: node2>]
>>> nodes[0].get_descendants()
[]

>>> nodes[0].get_descendants(True)
[<Node: node0>, <Node: node2>]


>>> for n in nodes:
...     print n, n.get_ancestors()
...
node0 []
node1 [<Node: node0>]
node2 [<Node: node0>]
node3 [<Node: node0>, <Node: node2>]
node4 [<Node: node0>, <Node: node2>]
node5 [<Node: node0>, <Node: node2>]
node6 [<Node: node0>, <Node: node2>]
node7 [<Node: node0>, <Node: node2>, <Node: node6>]
node8 [<Node: node0>, <Node: node2>, <Node: node6>]
node9 [<Node: node0>, <Node: node2>, <Node: node6>]
node10 [<Node: node0>, <Node: node2>, <Node: node6>]
node11 [<Node: node0>, <Node: node2>, <Node: node6>]
node12 [<Node: node0>, <Node: node2>, <Node: node6>]
node13 [<Node: node0>, <Node: node2>, <Node: node6>]
node14 [<Node: node0>, <Node: node2>, <Node: node6>]

多くの祖先が間違っているのはなぜですか。たとえば、ノード 10 には祖先 (0,1,10) が必要です。

私は何か間違ったことをしていますか、それとも django-mptt にバグがありますか?

4

1 に答える 1

14

バグがあるとは言えませんが、注意が必要な落とし穴があります。

子を親に追加すると、子のツリー属性がMPTT固有のlft値で正しく更新さrghtlevel ます。

ただし、django-mpttは、保持している親のバージョンを更新しません。データベース内のバージョンは更新されますが、ローカル変数内のコピーは更新されません(DjangoモデルインスタンスにはIDがないため、データベースまたは同じデータベース行を参照する他のインスタンスが更新されたときに更新されないことに注意してください) )。

これは、親オブジェクトに追加する次の子が間違った左と右の値を取得し、後で親を保存すると、その子も間違った値を持つことを意味します。

解決策は、子を追加するたびにデータベースから親を再ロードすることです。

for n in range(1,15):
    parent_pos = (n-1)/2
    parent = nodes[parent_pos]
    nodes[n].move_to(parent, 'last-child')
    nodes[n].save()
    nodes[parent_pos] = Node.objects.get(pk=parent.pk)
于 2010-01-28T09:08:06.567 に答える