【发布时间】:2019-11-21 15:43:00
【问题描述】:
我喜欢 Django ORM 在查询集中延迟加载相关对象的方式,但我想它是非常不可预测的。 查询集 API 不会在相关对象用于创建查询集时保留它们,从而在以后访问时再次获取它们。
假设我有一个 ModelA 实例(例如 instance_a),它是 的 N 个实例的外键(例如 for_a) >模型B。现在我想对具有给定 ModelA 实例作为外键的 ModelB 执行查询。
Django ORM 提供了两种方式:
- 在 ModelB 上使用
.filter():
b_qs = ModelB.objects.filter(for_a=instance_a)
for instance_b in b_qs:
instance_b.for_a # <-- fetches the same row for ModelA again
在此处产生 1 + N 个查询。
- 在 ModelA 实例上使用反向关系:
b_qs = instance_a.for_a_set.all()
for instance_b in b_qs:
instance_b.for_a # <-- this uses the instance_a from memory
仅在此处产生 1 个查询。
虽然可以使用第二种方式来实现结果,但它不是标准 API 的一部分,也不适用于所有场景。例如,如果我有 ModelB 的 2 个外键实例(例如,ModelA 和 ModelC),并且我想获取两者的相关对象其中。 类似以下的工作:
ModelB.objects.filter(for_a=instance_a, for_c=instance_c)
我想在这种情况下可以使用.intersection(),但我想要一种通过标准 API 实现此目的的方法。毕竟,覆盖这些情况需要更多的非标准查询集函数的代码,这对下一个开发人员可能没有意义。
那么,第一个问题,是否可以使用标准 API 本身优化此类场景? 第二个问题,如果现在不可以,能否通过 QuerySet 进行一些调整?
PS:这是我第一次在这里提问,如有错误请见谅。
【问题讨论】:
标签: python django foreign-keys django-queryset django-orm