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

ArK*_*rKi 6 python sql django

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

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)
    ...
Run Code Online (Sandbox Code Playgroud)

现在,我想对Item进行数据库查询,但是我想选择与该Item相关的对象,无论是Movie,Book还是Software。如果所有项目都是一种类型,例如电影,那么我可以执行以下操作:

Item.objects.prefetch_related('movie')
Run Code Online (Sandbox Code Playgroud)

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

Item.objects.prefetch_related('movie', 'book', 'software')
Run Code Online (Sandbox Code Playgroud)

不管它是什么类型,都会找到相关的对象,这会有效吗?有更好的方法吗?

kon*_*iik 5

我会假设OneToOneField■找related_name设为您的QuerySet实例表明,那就是'movie''book''software'分别。

要反向遍历您不需要的一对一关系prefetch_related,这很容易LEFT OUTER JOIN通过由select_related. 这意味着,你应该能够做到

Item.objects.select_related('movie', 'book', 'software')
Run Code Online (Sandbox Code Playgroud)

和每个返回项目实例将自动包含相应的缓存实例MovieBook以及Software(如果存在的话,当然)。

prefetch_related仅当您想避免具有多对多或多对一关系的 O(N) 查询问题时才需要,即具有ManyToManyField或 的反向遍历ForeignKey