我如何限制Django中的prefetch_related?

时间:2015-10-06 13:23:09

标签: django query-optimization django-orm

假设我的图像对象与标记对象有很多关系。

现在,我正在创建一个搜索视图来显示图像,并为每个图像显示标签,显然,聪明的做法是预取图像的标签。

但是我每次只显示15个图像,但我必须评估整个查询集,以便显示总体上有多少结果。 所以我需要为前15个元素预取标签

如果我在切片前预取标签:

images = watson.filter(queryset, query).prefetch_related('tags')
amount = images.count()
images = images[:15]

这非常糟糕,因为可能有数千个结果,每个结果都有很多标签。

但如果我先切片:

images = watson.filter(queryset, query).prefetch_related('tags')[:15]
amount = images.count()

现在我只预取15个结果的标签,这很好但是我不能在不进行其他查询的情况下计算结果。

如果我这样做:

images = watson.filter(queryset, query)
amount = len(images)
images = images.prefetch_related('tags')[:15]

我仍然最终访问数据库两次因为prefetch执行了新的数据库查询。

基本上我需要点击数据库一次以获取所有图像,但只预取前15个标记。

1 个答案:

答案 0 :(得分:1)

首先尝试调用count(),然后执行prefetch_related()并对查询集进行切片。

images = watson.filter(queryset, query)
amount = images.count()
images = images.prefetch_related('tags')[:15]

这将对计数执行一次查询,一次查询前15个图像,另一个查询预览标记。调用count()len()更好,因为它无法获取您不需要的图片。