[ACCEPTED]-django-mptt get_descendants for a list of nodes-descendant
Great thanks to Craig de Stigter answered 4 my question on django-mptt-dev group, in 3 case anybody need it I am kindly reposting 2 his solution from http://groups.google.com/group/django-mptt-dev/browse_thread/thread/637c8b2fe816304d
from django.db.models import Q import operator def get_queryset_descendants(nodes, include_self=False): if not nodes: return Node.tree.none() filters =  for n in nodes: lft, rght = n.lft, n.rght if include_self: lft -=1 rght += 1 filters.append(Q(tree_id=n.tree_id, lft__gt=lft, rght__lt=rght)) q = reduce(operator.or_, filters) return Node.tree.filter(q)
Example Node tree:
T1 ---T1.1 ---T1.2 T2 T3 ---T3.3 ------T3.3.3
Example 1 usage:
>> some_nodes = [<Node: T1>, <Node: T2>, <Node: T3>] # QureySet >> print get_queryset_descendants(some_nodes) [<Node: T1.1>, <Node: T1.2>, <Node: T3.3>, <Node: T3.3.3>] >> print get_queryset_descendants(some_nodes, include_self=True) [<Node: T1>, <Node: T1.1>, <Node: T1.2>, <Node: T2>, <Node: T3>, <Node: T3.3>, <Node: T3.3.3>]
Later versions of mptt already have this function built into the object manager. So the 1 solution to this is just as follows:
Django mptt uses the modified pre-order 20 tree traversal method as described in the 19 MySQL Managing Hierarchical Data document.
It has the following query for 18 returning all nodes in a tree below a certain 17 node:
SELECT node.name FROM nested_category AS node, nested_category AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt AND parent.name = 'ELECTRONICS' ORDER BY node.lft;
The secret is the parent.lft and parent.rgt 16 numbers, all children will have a node.lft 15 value between the two.
Obviously that example 14 presupposes only one parent and that you 13 need to use the parent name to find the 12 parent. As you have the parent node data 11 already you can do something like the following:
SELECT node.id FROM node_table WHERE node.lft BETWEEN parent.lft AND parent.rgt OR node.lft BETWEEN parent.lft AND parent.rgt
I'll 10 leave it as an exercise for you as to how 9 to generate a seperate BETWEEN clause for 8 each parent node (hint, " AND ".join)
Alternatively 7 you can use a the range generator on each 6 parent to obtain all the values between 5 each parent's lft and rgt values inclusive. That 4 then lets you use a giant IN statement rather 3 than lots of BETWEEN clauses.
Combine either 2 of the above with a RawQueryset and you 1 will get the models back.
More Related questions