def mptt_build_tree(queryset, children_key): ''' :param queryset: the entire tree, or portion of tree, you're trying to construct :param children_key: key to store children, can't be a field name that's already on the model :return: QuerySet, with children (also QuerySets) properly nested to each level present ''' nodes = OrderedDict() nodes_children = OrderedDict() for row in queryset: nodes[row.id] = row if nodes_children.get(row.parent_id): nodes_children[row.parent_id]._result_cache.append(row) else: nodes_children[row.parent_id] = QuerySet() nodes_children[row.parent_id]._result_cache = [row] for k, node in nodes.iteritems(): # Try to find the parent so we can attach the child nodes setattr(node, children_key, QuerySet()) children = getattr(node, children_key) children._result_cache = [] if nodes.get(node.parent_id): children = getattr(nodes[node.parent_id], children_key) children._result_cache.append(node) # Build out root nodes for the base level of the list root_nodes = QuerySet() root_nodes._result_cache = [] for node_id, node in nodes.iteritems(): if node.parent_id is None: root_nodes._result_cache.append(node) return root_nodes