【发布时间】:2015-12-18 11:08:18
【问题描述】:
我正在努力提高我的 Django 应用程序产生的数据库点击量,而我的抱怨之一是 Django 表单。
当我获取一个带有表单的页面时,它会从数据库中加载对象以填写ModelChoiceFields,这很棒。
当我发布一些表单数据时,表单会清理数据。现在,在表单的clean_foo 方法中,我想访问foo 对象关系之一:foo.bar。这将访问数据库以获取 bar 对象。
有什么方法可以让我预取bar?我的意思是当表单使用pk 来查找foo 对象时,我可以让它预取bar 吗?我可以在哪里做呢?
查看Django source code,似乎选择的对象是直接用.get()获取的,而不是作为.filter()的查询集
def to_python(self, value):
if value in self.empty_values:
return None
try:
key = self.to_field_name or 'pk'
value = self.queryset.get(**{key: value}) # <-- Right here
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return value
所以,这告诉我的是,我不应该在那里尝试任何事情。我能做的最好的事情是
def clean_foo(self):
foo = Foo.objects.filter(pk=self.cleaned_data['foo'].pk).select_related('bar')
[...]
在那里我可以预取其余逻辑所需的内容。所以它不会是 1 次查询,但我最多可以进行 2 次查询。
我意识到这开始听起来像是一个陈述而不是一个问题,所以如果可能的话,请证明我错了
【问题讨论】: