首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django-mptt:如何成功地移动节点

django-mptt:如何成功地移动节点
EN

Stack Overflow用户
提问于 2010-06-15 03:21:47
回答 2查看 4K关注 0票数 5

django-mptt似乎下定决心要把我逼疯。我正在尝试做一些相对简单的事情:我要删除一个节点,并且需要对该节点的子节点做一些合理的处理。也就是说,我想要将它们提升一个级别,这样它们就是其当前父代的父代的子代。

也就是说,如果树看起来像:

代码语言:javascript
复制
 Root
  |
Grandpa
  |
Father
|    |
C1   C2

我要删除父亲,并希望C1和C2是祖父的孩子。

下面是我使用的代码:

代码语言:javascript
复制
class Node(models.Model):
    first_name   = models.CharField(max_length=80, blank=True)
    parent       = models.ForeignKey('self', null=True, blank=True, related_name='children')

    def reparent_children(self, parent):
        print "Reparenting"
        for child in self.get_children():
            print "Working on", child.first_name, "to parent", parent.email
            parent = Node.objects.get(id=parent.id)
            child.move_to(parent, 'last-child')
            child.save()

所以我会打电话给:

代码语言:javascript
复制
father.reparent_children(grandpa)
father.parent = None
father.save()

这几乎行得通。孩子们报告他们的父母是外公:

代码语言:javascript
复制
c1.parent == grandpa  # True

祖父在它的孩子中有C1和C2

代码语言:javascript
复制
c1 in grandpa.children.all()   # True

然而,Root与这些孩子断绝了关系。

代码语言:javascript
复制
c1.get_root() == father  # c1's root is father, instead of Root

c1 in root.get_descendants()  # False

怎样才能让孩子们移动起来,而他们的根不会被破坏呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-15 20:41:01

第一次保存子对象(即reparent_children方法的最后一行)时,内部的lftrght值将会更改。save()不会更新你可能闲置的实例。我认为一种安全的方法是每次都从数据库中重新获取它们,如下所示:

代码语言:javascript
复制
def reparent_children(self, parent):
    print "Reparenting"
    for child in self.get_children():
        print "Working on", child.first_name, "to parent", parent.email
        parent = Node.objects.get(id=parent.id)
        current_child = Node.objects.get(id = child.id)
        current_child.move_to(parent, 'last-child')
        current_child.save()

我曾经使用过similar problems,这种方法解决了我的问题。

票数 6
EN

Stack Overflow用户

发布于 2017-10-07 03:31:00

最近几天,这个库真的把我搞糊涂了-- move_to似乎并不能真正实现我想要的功能,而且我的树一直不同步。我想出了一个更有信心的解决方案,以牺牲速度和非传统性为代价。

它围绕着管理器方法partial_rebuild here展开。

代码语言:javascript
复制
def delete_node(self):
    if not self.parent:
        print("Should not delete root node, confusing behavior follows")
        return
    tree_id = self.tree_id
    parent = self.parent

    for child in self.get_children():
        child.parent = parent
        child.save()

    self.delete()
    Node.objects.partial_rebuild(tree_id)

如果您愿意,可以将child.parent = parent替换为child.move_node(parent)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3040214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档