我有一个模型Node
看起来像这样:
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
每当我尝试访问孩子的孩子时,数据库就会被点击。
我怎样才能使它在单个数据库查询中获取节点,子节点,子节点的子节点等?
根据docs你可以这样做:
Restaurant.objects.prefetch_related('pizzas__toppings')
这将预取所有属于餐馆的比萨饼以及属于这些比萨饼的所有配料。这将导致总共3个数据库查询 - 一个用于餐馆,一个用于比萨饼,一个用于浇头。
或者您可以使用Prefetch对象来进一步控制预取操作。
from django.db.models import Prefetch
Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'), queryset=Toppings.objects.order_by('name')))