高效的ModelChoiceField初始数据

时间:2011-03-31 09:56:53

标签: python django forms orm django-forms

要为我的ModelChoiceFields设置初始数据,目前我执行以下操作:

foo = ModelChoiceField(label="Foo label",
                       queryset=Foo.objects.all(),
                       initial=Foo.objects.get(pk=14))

但我觉得这可能是不好的做法,&我不确定设置初始数据的最有效方法。 pk=14是默认为“N / A”的记录。

目前,根据我的理解,Foo.objects.all()& Foo.objects.get(pk=14)正在对数据库进行单独查询,这是否会导致昂贵的事务/冗余事务? Foo的数据库相当小,但我很好奇如何优化ModelChoiceField定义。

2 个答案:

答案 0 :(得分:2)

您正在进行两次查询,但它们会在完全不同的时间执行。

查询集很懒惰。在实际呈现表单之前,不会执行Foo.objects.all()中的查询。这意味着可用的Foo对象列表将始终是最新的。

但是,当表单定义时,即第一次导入其模块时,将执行Foo.objects.get(pk=14)。因此,只要服务器进程保持活动状态,此值就会持续存在于请求中。这很好,因为查询不是每次都进行,但可能很糟糕,即使稍后从数据库中删除该对象,该值仍将保留。

为了回答您的具体问题,您实际上每次只执行一次查询。

答案 1 :(得分:1)

是的,您正在进行两次查询,但您的代码非常清晰且易于阅读。除非您已对代码进行了分析并确定此行存在问题,否则您的代码就可以了。

如果您真的想避免两个查询,我建议您查看Django cache并缓存查询集的结果,以便在后续的网页浏览中避免使用它们。

initial = cache.get("foo_modelchoice_initial")
if initial is None:
    initial = Foo.objects.get(pk=14)
    cache.set("foo_modelchoice_initial", initial)

foo = ModelChoiceField(label="Foo label",
                   queryset=Foo.objects.all(),
                   initial=initial)

如果Foo.objects.all()变得非常大,那么此代码将变慢,但在这种情况下,您需要替换为AJAX查找。