好吧,我现在已经坚持这个问题了很长时间 . 去看了一些问题/答案和博客,在这一点上我不明白为什么这不起作用 .
我会尽可能地让我的榜样变得简单 .
假设我有一个ModelMultipleChoiceField:
myfield = ModelMultipleChoiceField(
queryset=SomeObject.objects.none(),
label='',
widget=forms.CheckboxSelectMultiple(
attrs={
'class': 'mtlz-checkbox-group',
'label': 'some label: '
}
),
required=False
)
我将queryset设置为none,因为我需要动态计算结果 . 请注意,这是在ModelForm中,并且该字段是我需要自定义的对象的字段(使用一些自定义窗口小部件) .
那么现在我正在改变 __init__()
方法中的查询集:
def __init__(self, *args, **kwargs):
super(EquipeForm, self).__init__(*args, **kwargs)
self.base_fields['myfield'].queryset = self.method()
这里 self.method()
是's computing my queryset, and it'正常工作的方法 . 所以,无论什么,选择都没有得到更新,除非我刷新(只需按f5,而不是缓存和东西) . 继续我的阅读,我读到 self.base_fields['myfield'].widget.choices
被缓存了,所以我不得不在我的init中强制"refresh":
def __init__(self, *args, **kwargs):
super(EquipeForm, self).__init__(*args, **kwargs)
self.base_fields['myfield'].queryset = self.method()
self.base_fields['myfield'].widget.choices = self.base_fields['myfield'].choices
使用pdb,我看到选项已更新,看起来也像小部件选择 . 但是,当我第一次来到我的表单时,显示最后的选项并且似乎是缓存 . 如果我再次按f5,它现在显示正确的选择 .
在最后一次尝试中,我在 __init__()
方法中声明了所有字段,但它是一样的 .
那我错过了什么?是否有任何其他缓存涉及,因为我的选择似乎在我的 __init__()
中发生了变化,但总是迟到一转?这是来自我的自定义小部件(来自普通小部件的herit)吗?
有关信息,请访问django 1.11 .
EDIT: self.method()
:
def method(self):
ids = []
if not self.instance.attribute:
for obj in SomeObject.objects.exclude(id=self.instance.id):
ids += obj.members.all().filter(
some_condiftion=False
).values_list('id', flat=True)
return SomeOtherObject.objects.filter(is_superuser=False) \
.exclude(id__in=ids).order_by('name')
SomeObject.members
是与 SomeOtherObject
相关的多个字段 . 这就是为什么我有一个 ModelMultipleChoiceField
.
在此先感谢您的帮助
1 回答
问题是您正在更新
self.base_fields
,这是该类的字段dict,而不是self.fields
,它是实例上的副本 .由于
fields
已在您更新base_fields
时创建,因此它使用旧版本的选项;下次渲染页面时,它将使用此次创建的版本 .