Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django mptt:如何成功地移动节点_Python_Django_Django Mptt - Fatal编程技术网

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

Python django mptt:如何成功地移动节点,python,django,django-mptt,Python,Django,Django Mptt,django mptt似乎决心要把我从脑海中赶走。我试图做一些相对简单的事情:我要删除一个节点,并且需要对节点的子节点做一些合理的事情。也就是说,我想把他们提升一级,这样他们就成为了他们当前父母的孩子 也就是说,如果树看起来像: Root | Grandpa | Father | | C1 C2 我要删除父亲,并希望C1和C2是爷爷的孩子 以下是我使用的代码: class Node(models.Model): first_name = models.CharF

django mptt似乎决心要把我从脑海中赶走。我试图做一些相对简单的事情:我要删除一个节点,并且需要对节点的子节点做一些合理的事情。也就是说,我想把他们提升一级,这样他们就成为了他们当前父母的孩子

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

 Root
  |
Grandpa
  |
Father
|    |
C1   C2
我要删除父亲,并希望C1和C2是爷爷的孩子

以下是我使用的代码:

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()
所以我会打电话给:

father.reparent_children(grandpa)
father.parent = None
father.save()
这几乎奏效了。孩子们称他们的父母为爷爷:

c1.parent == grandpa  # True
爷爷把C1和C2算在孩子们中间

c1 in grandpa.children.all()   # True
然而,根否认这些孩子

c1.get_root() == father  # c1's root is father, instead of Root

c1 in root.get_descendants()  # False

我如何让孩子们移动,他们的根不被腐蚀

内部
lft
rght
值将在您第一次保存孩子时更改(即
reparent_children
方法的最后一行)
save()
不会更新可能存在的实例。我认为这样做的安全方法是每次从数据库中重新提取它们,如下所示:

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

不久前,这种方法解决了我的问题。

这几天来,这个库真的让我很困惑——移动到似乎并没有达到我想要的效果,而且我的树一直不同步。我以牺牲速度和非传统性为代价,提出了一个我更有信心的解决方案

它围绕管理器方法
partial\u rebuild
展开


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

是否确定“father.parent=None”是删除节点的正确方法?在这种情况下,我实际上并没有删除节点-我正在存档它。我想把它从树上移开。不过,你有一个很好的观点,我并没有将其从树中删除。看起来,将父节点设置为“无”并保存实际上是从树中删除节点的方法(根据mptt测试用例),另一件事:让
Node
MPTTModel
继承和
NodeManager
treemanger
Dominic继承是很有帮助的,我最终使用了这个方法,它似乎很有效,尽管对于django mptt,我一直在质疑自己的理智。我不知道我是否真的解决了这个问题,或者把它藏在了其他地方。在Django应用程序中也有类似的问题。能够使用
parent.refresh\u from\u db()
解析。
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)