【问题标题】: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()

如何让它发挥作用? 谢谢。

【问题讨论】:

    标签: django django-models django-queryset


    【解决方案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 所示。

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 2014-02-22
      • 1970-01-01
      • 2012-01-14
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2018-03-31
      相关资源
      最近更新 更多