我的 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 不检索所有后代?
I'm using django-mptt 0.4.2 and have trouble with one of my data trees.
Here is the tree as seen in 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 |
+-------+-----+------+-------+
In my Python shell it looks the same:
>>> 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
The problem is when I use the .get_descendants() method from django.mptt:
>>> 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
Why doesn't django-mptt retrieve all the descendants?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
树处于不准确的状态:
parentnode:89919[left=1, right=10]
不能包含childnode:89924[left=10, right=11]
您可以在查询中看到它,它正在搜索
left >= 2 (paren_left+1)
和<= 9 (parent_right-1)
的子节点,您可能想要重建树以获得正确的结果。
您最近使用过
move_to
吗?看一下这里的注释:< code>move_to(target,position='first-child'),可能是相关的。inset_at
也可能会出现同样的问题,这是因为当使用insert_at
或move_to
时,您提供了一个在数据库中更新的父节点但不在内存中,因此在每一个操作之后您都必须获取父级的新副本。更多信息请参见:使用last-child的insert_node无法正常工作
The tree is in an inaccurate state:
parentnode:89919[left=1, right=10]
can not containchildnode:89924[left=10, right=11]
You can see it in the query, it's searching for child nodes with
left >= 2 (paren_left+1)
and<= 9 (parent_right-1)
You might want to rebuild the tree to obtain correct results.
Have you used
move_to
recently? Look at the note here:move_to(target, position='first-child')
, may be it's related.The same problem may arise with
inset_at
and it's due to fact that when usinginsert_at
ormove_to
you supply a parent node that is updated in the database but not in memory, so you have to get a fresh copy of the parent after each one of these actions.More info here:insert_node using last-child does not work correctly