【问题标题】:Django MPTT maximum elements in recursetree递归树中的Django MPTT最大元素
【发布时间】:2013-12-05 12:56:45
【问题描述】:

有没有办法使用 Django-MPTT 的 {% recursetree %} 呈现部分树而不从数据库中检索整个树?我需要显示深度优先搜索遇到的前 20 个节点。

其中任何一个(不检索完整树)都会导致异常:

# 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

另一方面,这确实有效,但会检索整个树:

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

如何在不从数据库中检索整个树的情况下做到这一点?

【问题讨论】:

    标签: django django-templates django-mptt mptt


    【解决方案1】:

    MPTT 使用预排序(这已经是深度优先搜索。)所以您需要做的就是在将查询集传递给递归树之前为其添加一个限制。

    如果你将查询集传递给recursetree,MPTT 会调用order_by(),但如果你传递一个列表,它就不能这样做。这种行为有点令人困惑,也给其他人带来了问题。

    我创建了一个ticket on MPTT 来解决这个问题。

    与此同时,您可以在 list() 调用之前进行切片:

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

    这将在数据库中进行限制,然后将查询集转换为列表,您可以将其传递给 recursetree 而无需尝试重​​新排序。

    【讨论】:

    • 谢谢,但这在{% recursetree %} 中给出了一个例外。请参阅我更新的问题。
    • 确实如此。已编辑以解决该问题。