在Django的數據庫查詢優化新手問題:Django的數據庫查詢優化
我有一個自定義模式表單編輯一個目標對象,我在構造函數中,我得到一個QuerySet的持有從相關訪客模式,具有多對多字段到目的地(見編輯使用自定義模型形式的原因)
print "loading initial choices"
visitor_choices, visitor_initial = [], []
visitor_set = self.instance.visitor_set.all()
print visitor_set
for obj in Visitor.objects.all():
visitor_choices.append((obj.pk, obj.name))
#if visitor_set.filter(pk=obj.pk # this hits the db every time!
if obj in visitor_set:
visitor_initial.append(obj.pk)
self.fields['visitors'].choices = visitor_choices
self.fields['visitors'].initial = visitor_initial
print "finished loading initial choices"
的想法是相關visitor_set加載到一個變量,以避免重複的查詢,以檢查是否每個訪問者存在於visitor_set。這是最好的方法嗎?我可以看到一個重複的查詢(第三個SELECT語句)選擇目標ID爲1的所有訪問者,但是這並不存在於我寫的代碼,它從哪裏來的?
loading initial choices
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testapp_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 LIMIT 21; args=(1,
)
[<Visitor: MIMA>, <Visitor: MIMO>, <Visitor: MIMU>]
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor"; args=()
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testapp_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 ; args=(1,)
finished loading initial choices
EDIT
Destination
的對象我指的是一個ManyToMany
場的Visitor
物體上的相關側。如果我的表單正在編輯Visitor對象本身,那麼Django會自動處理ManyToMany
字段。但要在Destination
的模型表單上執行此操作,我需要爲Visitor
添加多選字段,並自定義__init__
方法以加載它的選項和初始選擇。
問題不過是關於如何處理查詢集,以及神祕的第二個SQL加載多對多值,我也可以從外殼看到:
>>> from testapp.forms import DestinationForm
>>> from testapp.models import Destination, Visitor
>>> dest = Destination.objects.get(pk=1)
(0.001) SELECT "testapp_destination"."id", "testapp_destination"."destination" FROM "testapp_destination" WHERE "testapp_destination"."id" =
1 ; args=(1,)
>>> destinationForm = DestinationForm(instance=dest)
loading initial choices
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testap
p_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 LIMIT 21; args=(1,
)
[<Visitor: MIMA>, <Visitor: MIMO>, <Visitor: MIMU>]
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor"; args=()
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testap
p_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 ; args=(1,)
finished loading initial choices
>>>
感謝
你能解釋你想達到什麼嗎?對我來說,如果你爲其中'visitor'是'ManyToManyField'的模型生成一個'ModelForm',你就會默認做django應該做的事情? –
是的,你是對的,我的表單試圖保存一個'目的地'模型,它位於我的'訪問者'模型的ManytoMany字段的相關端,我將發佈模型來澄清。所以我可以有一個表格來保存'訪問者',它會自動處理ManyToMany,但是我想要探索這種做法。然而,我的問題是關於我處理查詢集的方式,以及我在日誌中看到的奇怪的附加sql語句 – xuloChavez