Django-mptt 完全有问题还是我做错了?

发布于 2024-08-19 10:08:52 字数 2007 浏览 11 评论 0原文

我尝试使用 django-mptt 但运气不佳。这是来自 svn 的最新 Python2.5、windows、sqlite3、Django 1.2pre、django-mptt。

代码:

model:

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)

setup:

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()

这应该创建一棵树,其中一个根和两个子节点挂在每个非叶节点上。

现在有趣的事情开始了:

>>> 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 中存在错误吗?

I'm attempting to use django-mptt with very little luck. This is with Python2.5, windows, sqlite3, Django 1.2pre , django-mptt latest from svn.

The code:

model:

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)

setup:

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()

This should create a tree with one root and two children hanging off of each non-leaf node.

Now the fun begins:

>>> 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>]

Why are so many of the ancestors wrong? For example, node 10 should have ancestors, (0,1,10)

Am I doing something wrong or are there bugs in django-mptt?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

土豪我们做朋友吧 2024-08-26 10:08:52

我不会说它有问题,但有一个你需要注意的问题。

当您向父级添加子级时,子级的树属性将使用 MPTT 特定的 lftrghtlevel 值正确更新。

但是,django-mptt 不会更新您所持有的父级版本。数据库中的版本已更新,但本地变量中的副本未更新(请记住,Django 模型实例没有标识,因此当数据库或引用同一数据库行的其他实例更新时,不会更新) )。

这意味着您添加到父对象的下一个子对象将获得错误的左值和右值,并且如果您随后保存父对象,它也将具有错误的值。

解决方案是每次添加子项时从数据库重新加载父项:

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)

I wouldn't say it's buggy, but there is a gotcha that you need to be aware of.

When you add a child to a parent, the child's tree attributes are correctly updated with the MPTT-specific lft, rght and level values.

However, django-mptt does not update the version of the parent that you are holding. The version in the database is updated, but the copy in your local variable is not (remember that Django model instances don't have identity, so don't get updated when the database, or other instances referring to the same database row, update).

This means that the next child you add to the parent object will get the wrong left and right values, and if you do subsequently save the parent that too will have the wrong values.

The solution is to reload the parent from the database each time you add a child:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文