如何在一对一关系可能不同的反向一对一关系中prefetch_related?

时间:2012-04-20 22:08:00

标签: python sql django

假设我有一个包含电影,书籍和软件的数据库,它们都继承了单个项目模型。

class Item(models.Model):
    ...

class Movie(models.Model):
    item = models.OneToOneField(Item)
    ...

class Book(models.Model):
    item = models.OneToOneField(Item)
    ...

class Software(models.Model):
    item = models.OneToOneField(Item)
    ...

现在我想在Item上进行数据库查询,但是我想要获取该项目的相关对象,无论是电影,书籍还是软件。如果所有项目都是一种类型,比如电影,那么我可以执行以下操作:

Item.objects.prefetch_related('movie')

但是,我需要能够获取相关对象,无论它是什么类型。我可以跑:

Item.objects.prefetch_related('movie', 'book', 'software')

这会找到相关对象,无论它是什么类型,这会有效吗?有没有更好的方法呢?

1 个答案:

答案 0 :(得分:3)

我认为OneToOneField已设置related_name,因为您的QuerySet示例分别表示'movie''book''software'。< / p>

要向后遍历一对一关系,您不需要prefetch_related,这可以通过LEFT OUTER JOIN自动生成的select_related轻松实现。这意味着,你应该能够做到

Item.objects.select_related('movie', 'book', 'software')

并且每个返回的Item实例将自动包含相应的MovieBookSoftware的缓存实例(当然,如果有的话)。

仅当您希望避免与多对多或多对一关系的O(N)查询问题时,才需要

prefetch_related,即使用ManyToManyField或反向遍历ForeignKey