Django prefetch_related孩子的孩子 [英] Django prefetch_related children of children
问题描述
我有一个模型 Node
,看起来像这样:
class Node(models.Model):
parent = models.ForeignKey('self',related_name ='children',on_delete = models.CASCADE)
一个节点可以有几个孩子,每个孩子可以有自己的孩子。
:
def show_child(node):
$ p $以外的每个循环命中数据库p>
for node.children.all()中的孩子:
show_child(child)
root_node = Node.objects.prefetch_related('children')。get(pk = my_node_id)#按预期两次命中数据库
print(现在测试查询)
root_node.children.all()#没有命中
root_node.children.all()#没有命中
root_node.children.all()#没有命中
root_node.children。 all()#没有命中
print( Test 2)
show_child(root_node)#除了第一个
每次我尝试访问ch的子级时数据库都会被命中
我如何做到这一点,以便它在单个数据库查询中获取节点,其子节点,其子节点等?
解决方案根据文档,您可以执行以下操作:
Restaurant.objects.prefetch_related ('pizzas__toppings')
这将预取属于餐厅的所有比萨饼,以及属于这些比萨饼的所有浇头。这将导致总共3个数据库查询-一个针对餐厅,一个针对披萨和一个针对浇头。
或者您可以使用Prefetch对象来进一步控制预取操作。
从django.db.models导入Prefetch
Restaurant.objects。 prefetch_related(Prefetch('pizzas__toppings'),queryset = Toppings.objects.order_by('name')))
I have a model
Node
that looks something like that:class Node(models.Model): parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE)
A Node can have several children, and each of these children can have its own children.
If I do:
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
The database gets hit every time I try to access the children of a child.
How could I make it so that it gets the node, its children, the children of its children, etc, in a single database query?
解决方案According to the docs you can do this:
Restaurant.objects.prefetch_related('pizzas__toppings')
This will prefetch all pizzas belonging to restaurants, and all toppings belonging to those pizzas. This will result in a total of 3 database queries - one for the restaurants, one for the pizzas, and one for the toppings.
or you can use the Prefetch object to further control the prefetch operation.
from django.db.models import Prefetch Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'), queryset=Toppings.objects.order_by('name')))
这篇关于Django prefetch_related孩子的孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!