我的django-mptt树出了什么问题?

时间:2011-04-02 09:53:26

标签: django django-mptt

我正在使用django-mptt 0.4.2并且我的一个数据树出现问题。

这是mysql中的树;

mysql> select id, lft,rght,level from my_object where tree_id=30613;
+-------+-----+------+-------+
| id    | lft | rght | level |
+-------+-----+------+-------+
| 89919 |   1 |   10 |     0 | 
| 89924 |  10 |   11 |     1 | 
| 89930 |   6 |    9 |     1 | 
| 90401 |   2 |    5 |     1 | 
| 90406 |   3 |    4 |     2 | 
| 90407 |   7 |    8 |     2 | 
+-------+-----+------+-------+

在我的Python shell中它看起来是一样的:

>>> obj = MyObject.objects.filter(tree_id=30613)
>>> for o in obj:
...     print "%5d %2d %2d %1d" % (o.id, o.lft, o.rght, o.level)
... 
89919  1 10 0
89924 10 11 1
89930  6  9 1
90401  2  5 1
90406  3  4 2
90407  7  8 2

问题是当我使用django.mptt中的.get_descendants()方法时:

>>> parent_node = MyObject.objects.get(id=89919)
>>> descendants = parent_node.get_descendants()
>>> for o in descendants:
...     print "%5d %2d %2d %1d" % (o.id, o.lft, o.rght, o.level)
... 
90401  2  5 1
90406  3  4 2
89930  6  9 1
90407  7  8 2


>>> print descendants.query # Formatted for readability
SELECT * FROM `my_obj` 
WHERE (
    `my_obj`.`lft` <= 9  
    AND `my_obj`.`lft` >= 2  
    AND `my_obj`.`tree_id` = 30613 
) ORDER BY `my_obj`.`tree_id` ASC, `my_obj`.`lft` ASC

为什么django-mptt没有检索所有后代?

1 个答案:

答案 0 :(得分:2)

树处于不准确的状态:

parentnode:89919[left=1, right=10]不能包含childnode:89924[left=10, right=11]

您可以在查询中看到它,它正在搜索left >= 2 (paren_left+1)<= 9 (parent_right-1)

的子节点

您可能希望重建树以获得正确的结果。

您最近使用过move_to吗?请看这里的注释:move_to(target, position='first-child'),可能是相关的。

inset_at可能会出现同样的问题,这是因为当使用insert_atmove_to时,您提供的是在数据库中更新但未在内存中更新的父节点,因此在完成这些操作后,您必须获得父母的新副本。

此处有更多信息:insert_node using last-child does not work correctly