2

Is there a way to present a partial tree using Django-MPTT's {% recursetree %} without retrieving the entire tree from database? I need to show the first 20 nodes encountered by a Depth First Search.

Either of these (which do not retrieve the full tree) cause an exception:

# resulting querySet passed to {% recursetree %} in template
Thing.objects.all()[:20]

# directly sliced in template
{% recursetree all_nodes|slice:":20" %} 

AssertionError while rendering: Cannot reorder a query once a slice has been taken.

This on the other hand does work, but retrieves the entire tree:

 # resulting querySet passed to {% recursetree %} in template
 list(Thing.objects.all())[:20]

How can I do this without retrieving the entire tree form the DB?

royron
  • 23
  • 1
  • 4

1 Answers1

1

MPTT uses pre-order (which is a depth-first search already.) So all you need to do is add a limit to your queryset before passing it to recursetree.

MPTT calls order_by() if you pass a queryset to recursetree, but it can't do that if you pass a list. That behaviour is kind of confusing and has caused other people issues too.

I've created a ticket on MPTT to address this.

In the meantime, you can just do the slicing before the list() call:

list(Thing.objects.all()[:20])

That will do the limit in the database, then convert the queryset to a list, which you can pass to recursetree without it trying to reorder things.

craigds
  • 2,072
  • 14
  • 25