Django prefetch_related 与反向外键查找

43T*_*cts 5 django foreign-keys django-queryset

鉴于Django 文档中的这些模型:

class Topping(models.Model):
    name = models.CharField(max_length=30)

class Pizza(models.Model):
    name = models.CharField(max_length=50)
    toppings = models.ManyToManyField(Topping)
Run Code Online (Sandbox Code Playgroud)

我想得到浇头并用他们的pizza_set做一些事情:

toppings = Topping.objects.all()

for topping in toppings:
   pizzas_with_this_topping = topping.pizza_set()
   # do stuff with pizzas_with_this_topping
Run Code Online (Sandbox Code Playgroud)

如何使用 prefetch_related(或其他技术)获取所有披萨数据,而无需为每个 Topping 中的每个 Pizza 访问数据库?

Bob*_*Bob 7

像这样预取它们:

toppings = Topping.objects.prefetch_related('pizza_set')
Run Code Online (Sandbox Code Playgroud)

那么以下不会命中数据库:

for topping in toppings:
    pizzas_with_toppings = topping.pizza_set.all()
Run Code Online (Sandbox Code Playgroud)

我想补充一点,Django 努力使简单的事情易于使用(毫无疑问,Django 做得很好),但这显然使 Django 做了很多隐含的事情,这些事情在应用程序中并不明显代码,所以当你做一些高级的事情时,你应该预料到意想不到的,阅读 Django 文档,它阐明了所有的魔法,并使用 Django 调试工具栏等工具来验证一切是否如你所愿。

  • 就我而言,似乎每次您在相关管理器上使用“.all”查询(又名:“..._set”)时,实际上数据库都会被命中。我使用 len(connection.queries) 检查了这一点。不知道该怎么办。 (3认同)