在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