如何在反向一对一关系中使用prefetch_related,其中一对一关系可能不同?

6
假设我有一个数据库,其中包含电影、书籍和软件,它们都继承自一个单一的“项目”模型。
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.objects.prefetch_related('movie')

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

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

这将无论对象类型如何都能找到相关对象吗?这种方法有效吗?有更好的方法吗?
1个回答

9
我假设你的查询集例子中设置了related_name作为OneToOneField,分别为'movie'、'book'和'software'。
要向后遍历一对一关系,不需要使用prefetch_related,这是可以通过select_related自动生成的LEFT OUTER JOIN轻松实现的。也就是说,你应该能够执行以下操作:
Item.objects.select_related('movie', 'book', 'software')

每个返回的Item实例都会自动包含相应的缓存电影书籍软件(如果有的话)实例。

prefetch_related仅在您想要避免处理多对多或多对一关系时出现O(N)查询问题时才需要使用,也就是说,当涉及到ManyToManyFieldForeignKey的反向遍历时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接