【问题标题】:Using django select_related with an additional filter将 django select_related 与附加过滤器一起使用
【发布时间】:2019-03-31 00:59:17
【问题描述】:

我正在尝试找到执行查询的最佳方式,但我对 prefetch_related 和 select_related 用例感到困惑。

我有一个 3 表外键关系:A -> 有 1-many B h-> 作为 1-many C。

class A(models.model):
   ...

class B(models.model):
   a = models.ForeignKey(A)

class C(models.model):
   b = models.ForeignKey(B)
   data = models.TextField(max_length=50)

我正在尝试获取所有符合条件的 A 实例的所有 C.data 列表(A 的实例及其所有子项),所以我有这样的内容:

qs1 = A.objects.all().filter(Q(id=12345)|Q(parent_id=12345))
qs2 = C.objects.select_related('B__A').filter(B__A__in=qs1)

但我对 (Prefetch docs 表示:

任何暗示不同数据库查询的后续链接方法 将忽略以前缓存的结果,并使用新的检索数据 数据库查询

我不知道这是否适用于这里(因为我正在使用 select_related),但阅读它会让我觉得从执行 select_related 获得的任何东西在我执行过滤器时都会丢失。

我的两部分查询是否尽可能最佳?据我所知,我认为我不需要预取,尽管我注意到我可以将 select_related 换成 prefetch_related 并获得相同的结果。

【问题讨论】:

  • 您可以使用查询集的query 属性检查实际的sql。

标签: django filter django-queryset


【解决方案1】:

我认为您的问题是由误解引起的。 select_related(和prefetch_related)是一个优化,专门用于返回相关模型中的值以及原始查询。 从不需要它们。

更重要的是,两者都对filter 没有任何影响。无论您是否使用select_related,Django 都会自动执行相关的连接和子查询以进行查询。

【讨论】:

  • 考虑到你所说的,看来我所需要的只是 C.objects.filter(b__a__in=qs1) 所以是的,看起来我已经很好地并且真正地误解了文档。跨度>
猜你喜欢
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2017-08-17
  • 2014-03-30
  • 2011-10-01
  • 2019-09-26
  • 2021-04-02
相关资源
最近更新 更多