我有一个模型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
每次我尝试访问一个孩子的孩子时,数据库都会受到攻击。
我如何做到这一点,以便它在单个数据库查询中获取节点,其子节点,其子节点等?
答案 0 :(得分:1)
根据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')))