我有两个简单的Django模型:
class PhotoStream(models.Model):
cover = models.ForeignKey('links.Photo')
creation_time = models.DateTimeField(auto_now_add=True)
class Photo(models.Model):
owner = models.ForeignKey(User)
which_stream = models.ManyToManyField(PhotoStream)
image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage())
目前我唯一拥有的数据是6张照片,全部属于1张照片。我正在尝试以下方法在形成照片流查询集时预取所有相关照片:
queryset = PhotoStream.objects.order_by('-creation_time').prefetch_related('photo_set')
for obj in queryset:
print obj.photo_set.all()
#print connection.queries
通过调试工具栏进行检查,我发现如果删除语句的prefetch_related
部分,上面的查询数量完全相同。它显然不起作用。我也尝试了prefetch_related('cover')
- 这也不起作用。
任何人都可以指出我做错了什么,以及如何解决它?我的目标是获取查询集中每个照片流的所有相关照片。我怎么可能这样做?
运行for循环后打印connection.queries
包括:
SELECT ("links_photo_which_stream"."photostream_id") AS "_prefetch_related_val", "links_photo"."id", "links_photo"."owner_id", "links_photo"."image_file" FROM "links_photo" INNER JOIN "links_photo_which_stream" ON ("links_photo"."id" = "links_photo_which_stream"."photo_id") WHERE "links_photo_which_stream"."photostream_id" IN (1)
注意:我已经简化了问题中发布的模型,因此上面的查询不包含实际出现在输出中的某些字段,但与此问题无关。
答案 0 :(得分:0)
以下是prefetch_related
的一些摘录:
另一方面,
**prefetch_related**
对每个关系进行单独查找,并在Python中执行‘joining’
。
还有一些:
>>> Pizza.objects.all().prefetch_related('toppings')
这意味着每个比萨饼
self.toppings.all()
;现在,每次调用self.toppings.all()
时,它都会在一个查询中填充的预取的QuerySet缓存中找到它们,而不必转到数据库中。
因此,您看到的查询次数将始终相同,但如果您使用prefetch_related
,则不会为每个photostream
点击数据库,而是会点击{ {1}}它已经构建并从那里获得prefetched QuerySet cache
。