【问题标题】:Annotate a `selected_related`'d object in Django在 Django 中注释一个`selected_related`d 对象
【发布时间】:2020-04-05 06:32:47
【问题描述】:

我正在构建一个模型的查询集,并希望在我 selected_related'ing 的相关模型上添加一个注释到查询集中。假设:

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

class Author(models.Model):
    name = models.TextField()   

我选择Book.objects.all().select_related(),并想用awesome=True 注释作者。我可以自己解析查询集并更改对象,但是有没有更干净的面向 ORM 的方法呢?倒转操作以选择作者是不可取的。

【问题讨论】:

  • 根据模型设计,请根据您的预期查询输出更新您的 under。

标签: django django-rest-framework django-orm


【解决方案1】:

对于这个prefetch_related 可能是更合适和更干净的解决方案。

from django.db import models

q = Book.objects.all().prefetch_related(
    models.Prefetch(
        "author",
        queryset=Author.objects.all().annotate(
            awesome=models.Value(
                True,
                output_field=models.BooleanField()
            )
        )
    )
)

这将导致对数据库进行两次查询,而不是使用select_related 进行第二次查询,当您访问.manager 时会进行第二次查询,总共仍然只有两次查询,而不是每本书都额外查询一次, 除非以后访问.manager 时使用了不同的查询集(即带有过滤器)。

【讨论】:

  • Hunh,我完全错过了粗体部分:“另一方面,prefetch_related 对每个关系进行单独查找,并在 Python 中进行“加入”。这允许它预取许多- 除了由 select_related 支持的外键和一对一关系之外,还不能使用 select_related 来完成对多和多对一的对象。"谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-04-11
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 2016-02-27
  • 1970-01-01
相关资源
最近更新 更多