django-mptt:如何成功移动节点
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
然而,Root 与这些孩子断绝关系。
c1.get_root() == father # c1's root is father, instead of Root
c1 in root.get_descendants() # False
怎样才能让孩子们动起来,而且他们的根不被腐蚀呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一次保存子项时(即
reparent_children
方法的最后一行),内部lft
和rght
值将会更改。save()
不会更新您可能拥有的实例。我认为一种安全的方法是每次从数据库中重新获取它们,如下所示:我有 类似问题不久前,这种方法解决了我的问题。
The internal
lft
andrght
values will change the first time you save a child (i.e. the final line of yourreparent_children
method).save()
doesn't update instances you may have lying around. I think a safe way to do this would be to refetch them from the database each time, like this:I had similar problems a while back, and that approach solved my problem.
最近几天这个库真的让我很困惑—— move_to 似乎并没有真正做到我想要的,而且我的树一直不同步。我想出了一个我更有信心的解决方案,但代价是速度和非传统性。
它围绕管理器方法
partial_rebuild
此处。如果您愿意,可以将 child.parent =parent 替换为 child.move_node(parent)
This library has really confused me these last few days -- move_to does not really seem to do what I want it to, and my tree keeps getting out of sync. I came up with a solution that I'm more confident in, at the expense of speed and nontraditional-ness.
It revolves around the manager method
partial_rebuild
here.You can replace child.parent = parent with child.move_node(parent) if you'd like