这两者是相同的
MyClass.objects.prefetch_related('relation')
MyClass.objects.prefetch_related(
Prefetch('relation', to_attr='relation_as_list')
)
可以使用预取对象,以进一步控制预取操作(docs)
你只需要当你需要一个Prefetch
对象改进prefetch_related
的结果。例如,你可能不需要每个relation
,但是特定的,所以你可以改进预取查询。
使用to_attr建议过滤下来的时候预取结果,因为它比在相关管理器的缓存存储过滤结果更加明确(docs)
to_attr
不给额外的性能提升,它允许使关系更不明确,并且使得可以预取与不同的QuerySet相同的关系。
MyClass.objects.prefetch_related(
Prefetch('same_relation', queryset=queryset_one, to_attr='relation_set_one')
Prefetch('same_relation', queryset=queryset_two, to_attr='relation_set_two')
)
如果预取不同Prefetch
对象相同的关系,也将是他们每个人的其他查询。生成的预取QuerySets将存储在一个列表中,但结果不是像您假设为relation_as_list
的列表。它们是QuerySets。在你的榜样,访问既关系可以用all()
来完成,像my_obj.relation_as_list.all()
和my_obj.relation.all()
关于性能提升
综上所述,prefetch_related
获取一个(附加)DB相关的对象打这哪里是性能提升来自于。使用Prefetch
对象可以进一步优化此数据库调用。
for item in yourmodel.object.all():
for a_relation in item.relation.all():
do_something(a_relation)
# WITHOUT PREFETCH RELATED YOU'D HIT DB EVERY TIME!!
# IMAGINE IF YOU HAD TONS OF ITEMS
# THIS WILL HAVE 2 DB HITS
for item in yourmodel.object.prefetch_related('relation').all().:
for a_relation in item.relation.all():
do_something(a_relation)