Par*_*and 5 python django django-mptt
django-mptt似乎决定让我失去理智.我正在尝试做一些相对简单的事情:我要删除一个节点,并且需要对节点的子节点做一些合理的事情.也就是说,我想将它们提升一级,这样他们就是现在父母的父母.
也就是说,如果树看起来像:
Root
|
Grandpa
|
Father
| |
C1 C2
Run Code Online (Sandbox Code Playgroud)
我要删除父亲,并希望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()
Run Code Online (Sandbox Code Playgroud)
所以我打电话给:
father.reparent_children(grandpa)
father.parent = None
father.save()
Run Code Online (Sandbox Code Playgroud)
这很有效 - 差不多.孩子们报告他们的父母为爷爷:
c1.parent == grandpa # True
Run Code Online (Sandbox Code Playgroud)
爷爷的孩子中有C1和C2
c1 in grandpa.children.all() # True
Run Code Online (Sandbox Code Playgroud)
然而,Root拒绝了这些孩子.
c1.get_root() == father # c1's root is father, instead of Root
c1 in root.get_descendants() # False
Run Code Online (Sandbox Code Playgroud)
如何让孩子们移动,他们的根不会被破坏?
内部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()
Run Code Online (Sandbox Code Playgroud)
我不久前有类似的问题,这种方法解决了我的问题.
| 归档时间: |
|
| 查看次数: |
3102 次 |
| 最近记录: |