我的Django应用程序有一个名为Treenode的模型,它通过继承MPTTModel
(版本0.6.1)来实现树。该模型如下:
from mptt.models import MPTTModel, TreeForeignKey
class Treenode(MPTTModel):
name = models.CharField(max_length=255)
parent = TreeForeignKey('self', null=True, blank=True)
class MPTTMeta:
order_insertion_by = ['name']
def __unicode__(self):
return "%s (#%s)" % (self.name, self.pk)
现在看看当我开始创建这个模型的实例时会发生什么:
>>> a = Treenode(name="S", parent=None,); a.save()
>>> b = Treenode(name="B", parent=None,); b.save()
>>> c = Treenode(name="C", parent=a,); c.save()
>>> print "b.id = %s; b.name = %s; b.get_children() = %s; b.get_descendants() = %s" % (b.id, b.name, b.get_children(), b.get_descendants())
b.id = 2; b.name = B; b.get_children() = []; b.get_descendants() = []
>>> x = Treenode.objects.get(name="B")
>>> print "x.id = %s; x.name = %s; x.get_children() = %s; x.get_descendants() = %s" % (x.id, x.name, x.get_children(), x.get_descendants())
x.id = 2; x.name = B; x.get_children() = []; x.get_descendants() = [<Category: C (#3)>]
你看到了这个bug吗? x
与b
的实例相同 - 只是从数据库中检索。但MPTT错误地报告实例C
是x
的后代。不是!
我对此进行了大量的实验,以隔离和识别问题。我发现,如果我将实例a
的名称属性从“S”更改为“A”,问题就会消失。我还发现如果从模型中删除嵌套的MPTTMeta
类,问题就会消失。这向我表明MPTTMeta的order_insertion_by代码存在问题。任何人都可以确认这一点,或者知道是否有修复方法吗?
作为补充证据,当我有MPTTMeta(破碎)时,我已经包含了Treenode数据库表的截图,之后我删除了MPTTMeta(工作)以进行比较。