Is django-mptt completely buggy, or am I doing it wrong?

I am trying to use django-mptt with very little luck. This is with Python2.5, windows, sqlite3, Django 1.2pre, django-mptt the last of svn.

The code:

Model:

class Node(models.Model): name = models.CharField(max_length=20, blank=True) parent = models.ForeignKey('self', null=True, blank=True, related_name='children') def __unicode__(self): return self.name mptt.register(Node) 

Setup:

 nodes = [] for i in range(15): n = Node(name='node'+str(i)) n.save() nodes.append(n) nodes[0].move_to(None) nodes[0].save() for n in range(1,15): nodes[n].move_to(nodes[(n-1)/2],'last-child') nodes[n].save() 

This should create a tree with one root and two children hanging from each non-leaf node.

Now the fun begins:

 >>> nodes[0].children.all() [<Node: node1>, <Node: node2>] >>> nodes[0].get_descendants() [] >>> nodes[0].get_descendants(True) [<Node: node0>, <Node: node2>] >>> for n in nodes: ... print n, n.get_ancestors() ... node0 [] node1 [<Node: node0>] node2 [<Node: node0>] node3 [<Node: node0>, <Node: node2>] node4 [<Node: node0>, <Node: node2>] node5 [<Node: node0>, <Node: node2>] node6 [<Node: node0>, <Node: node2>] node7 [<Node: node0>, <Node: node2>, <Node: node6>] node8 [<Node: node0>, <Node: node2>, <Node: node6>] node9 [<Node: node0>, <Node: node2>, <Node: node6>] node10 [<Node: node0>, <Node: node2>, <Node: node6>] node11 [<Node: node0>, <Node: node2>, <Node: node6>] node12 [<Node: node0>, <Node: node2>, <Node: node6>] node13 [<Node: node0>, <Node: node2>, <Node: node6>] node14 [<Node: node0>, <Node: node2>, <Node: node6>] 

Why are so many ancestors wrong? For example, node 10 must have ancestors, (0,1,10)

Am I doing something wrong or are there errors in django-mptt?

+7
django mptt django-mptt
source share
1 answer

I would not say that this is a buggy, but there is information about what you need to know.

When a child is added to the parent, the attributes of the child tree will be correctly updated using the lft , rght and level values ​​defined in MPTT.

However, django-mptt does not update the version of the parent you are holding. The version in the database is updated, but there is no copy in your local variable (remember that instances of the Django model do not have an identifier, so do not update when the database or other instances that reference the same database row are updated).

This means that the next child that you add to the parent will receive the wrong values ​​on the left and right, and if you subsequently save the parent, which will also have the wrong values.

The solution is to reload the parent from the database every time you add a child:

 for n in range(1,15): parent_pos = (n-1)/2 parent = nodes[parent_pos] nodes[n].move_to(parent, 'last-child') nodes[n].save() nodes[parent_pos] = Node.objects.get(pk=parent.pk) 
+14
source share

All Articles