Eld*_*mir 4 python forms django
我正在努力改进我的Django应用程序所做的数据库命中量,而且我的一个抱怨是使用Django表单.
当我使用表单获取页面时,它将从数据库加载对象以填充ModelChoiceFields,这很好.
当我发布一些表单数据时,表单将清理数据.现在,在我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
Run Code Online (Sandbox Code Playgroud)
那么,那告诉我的是我不应该在那里尝试任何东西.我能做的最好的事情是
def clean_foo(self):
foo = Foo.objects.filter(pk=self.cleaned_data['foo'].pk).select_related('bar')
[...]
Run Code Online (Sandbox Code Playgroud)
在那里,我可以预取我需要的其余逻辑.所以它不会是1个查询,但我最多只能查询2个查询.
我意识到这听起来像是一个陈述而不是一个问题,所以如果可能的话,请证明我是错的
您似乎可以select_related直接在您的字段的查询集定义中使用:
class MyForm(forms.ModelForm):
my_field = forms.ModelChoiceField(queryset=Foo.objects.select_related('bar'))
Run Code Online (Sandbox Code Playgroud)