Django prefetch_儿童的相关儿童

Django prefetch_儿童的相关儿童,django,django-orm,Django,Django Orm,我有一个模型节点,看起来像这样: class Node(models.Model): parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE) 一个节点可以有几个子节点,每个子节点都可以有自己的子节点 如果我这样做: def show_child(node): for child in node.children.all(): show_child(

我有一个模型
节点
,看起来像这样:

class Node(models.Model):
    parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE)
一个节点可以有几个子节点,每个子节点都可以有自己的子节点

如果我这样做:

def show_child(node):
    for child in node.children.all():
        show_child(child)

root_node = Node.objects.prefetch_related('children').get(pk=my_node_id) # hit database twice, as expected
print("Now testing queries")
root_node.children.all()  # no hit
root_node.children.all()  # no hit
root_node.children.all()  # no hit
root_node.children.all()  # no hit
print("Test 2")
show_child(root_node)  # hit database for every loop except the first
每次我试图访问一个孩子的孩子时,数据库都会被击中

如何使其在单个数据库查询中获取节点、其子节点、其子节点的子节点等?

根据,您可以执行以下操作:

Restaurant.objects.prefetch_related('pizzas__toppings')
这将预取属于餐厅的所有比萨,以及属于这些比萨的所有配料。这将导致总共3个数据库查询-一个用于餐馆,一个用于比萨饼,一个用于配料

也可以使用预回迁对象进一步控制预回迁操作

from django.db.models import Prefetch

Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'), queryset=Toppings.objects.order_by('name')))

我已经在我的问题中使用了预回迁。我想知道的是,我是否可以在一个数据库查询中获取所有内容。此外,在我的例子中,我可以在toppings上有toppings,toppings上有toppings,等等,即使我不知道层次结构有多远,我也希望得到它们。@RyanPergent您可以查看
select\u related
:返回一个查询集,该查询集将“遵循”外键关系,在执行查询时选择其他相关对象数据。这是一个性能提升器,它会导致单个更复杂的查询,但意味着以后使用外键关系将不需要数据库查询。是的,谢谢,但我已经调查过了。我可以使用与预回迁单个项目(如父项)相关的select_,但不能使用它来获取子项列表。@RyanPergent确定吗?文档中有一个这样做的例子:然后调用
Book.objects。选择“相关的('author\u homely')。get(id=4)
将缓存相关的人和相关的城市,但是
author
homely
是单个对象。它不适用于像
作者
城市
这样的列表。设法用另一种方法使其工作: