Django prefetch_related查询无法按需运行,需要进行故障排除

时间:2016-05-02 00:21:07

标签: django django-models django-views django-queryset

我有两个简单的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)

注意:我已经简化了问题中发布的模型,因此上面的查询不包含实际出现在输出中的某些字段,但与此问题无关。

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