好吧,我现在已经陷入了这个问题很久了。 去看了一些问题/答案和博客,在这一点上我不明白为什么这不起作用。
我会尽可能地让我的榜样变得简单。
假设我有一个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()
是一个计算我的查询集的方法,它运行正常。
所以,无论什么,选择都没有得到更新,除非我刷新(只需按f5,而不是缓存和东西)。继续阅读,我读到self.base_fields['myfield'].widget.choices
被缓存了,所以我不得不在我的init中强制“刷新”:
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。
修改
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
。
提前感谢您的帮助
答案 0 :(得分:1)
问题是您正在更新self.base_fields
,这是类的字段dict,而不是self.fields
,它是实例上的副本。
由于您在更新fields
时已创建base_fields
,因此它使用旧版本的选项;下次渲染页面时,它将使用此次创建的版本。