我正在努力改进我的Django应用程序所做的数据库命中量,而且我的一个抱怨是使用Django表单.
当我使用表单获取页面时,它将从数据库加载对象以填充ModelChoiceField
s,这很好.
当我发布一些表单数据时,表单将清理数据.现在,在我clean_foo
的表单方法中,我想访问其中一个foo
对象关系:foo.bar
.这将命中数据库以获取bar
对象.
有什么办法让我预取bar
吗?我的意思是当表单使用pk
查找foo
对象时,我可以预取它bar
吗?我可以在哪里这样做?
看看Django源代码,似乎所选对象是直接获取的,.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个查询.
我意识到这听起来像是一个陈述而不是一个问题,所以如果可能的话,请证明我是错的
您似乎可以select_related
直接在您的字段的查询集定义中使用:
class MyForm(forms.ModelForm): my_field = forms.ModelChoiceField(queryset=Foo.objects.select_related('bar'))