Django:prefetch_related() 是不是遵循反向关系查找?
Posted
技术标签:
【中文标题】Django:prefetch_related() 是不是遵循反向关系查找?【英文标题】:Django: Does prefetch_related() follow reverse relationship lookup?Django:prefetch_related() 是否遵循反向关系查找? 【发布时间】:2012-02-28 21:23:21 【问题描述】:我在 django 1.4 中从trunk 尝试了 prefetch_related(),但无法预取反向查找。
我的简化模型(每本书都有很多价格):
class Book(models.Model):
# some fields
class Price(models.Model):
book = models.ForeignKey(Book)
我的观点的查询:
books = Book.objects.prefetch_related('price')
然后,我收到了 AttributeError 消息:
AttributeError: Cannot find 'price' on Book object, 'price' is an invalid parameter to prefetch_related()
如何让它发挥作用? 谢谢。
【问题讨论】:
【参考方案1】:定义相关名称:
class Price(models.Model):
book = models.ForeignKey(Book, related_name='prices')
然后使用它:
books = Book.objects.prefetch_related('prices')
【讨论】:
你的回答让我想起了 FOO_set,所以更正也可以是 .prefetch_related('price_set')。顺便说一句,非常感谢 我无法在 shell 中重现它。仍然做单独的查询,我期待加入。 您好!我也试过这个,但正如@pdvyas 所说,有单独的查询。这不会进行连接...prefetch_related
不进行连接,它只是收集相关对象 ID,然后在单个查询中获取这些对象并在 Python 中生成这些“连接”。见:docs.djangoproject.com/en/dev/ref/models/querysets/…
@jan-pöschko,似乎是定义related_name
的(更简单的)替代方法,是使用price_set
名称来引用关系。我已经添加了一个描述这一点的答案,但也许最好在你的(接受的)分析器中参考我的答案,或者在你的分析器中包含我的文本?【参考方案2】:
当您没有为关系定义related_name
时,反向关系会附加_set
。从对象(例如some_book.price_set.all()
)访问反向关系时就是这种情况,但这也适用于prefetch_related
:
books = Book.objects.prefetch_related('price_set')
请注意,这似乎与过滤器不同,过滤器确实接受没有_set
的其他模型的名称(例如Books.objects.filter(price__currency='EUR')
)。
上面是用 1.11.8 测试的(不是在这个特定的代码上,而是在我自己的类似代码上)。
或者,您可以添加related_name
,如上面的 Jan Pöschko 所示。
【讨论】:
以上是关于Django:prefetch_related() 是不是遵循反向关系查找?的主要内容,如果未能解决你的问题,请参考以下文章
prefetch_related 上的 Django ORM 注释