這兩者是相同的
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)