Django ModelChoiceField选择不更新

时间:2018-02-15 09:39:37

标签: python django

好吧,我现在已经陷入了这个问题很久了。 去看了一些问题/答案和博客,在这一点上我不明白为什么这不起作用。

我会尽可能地让我的榜样变得简单。

假设我有一个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

提前感谢您的帮助

1 个答案:

答案 0 :(得分:1)

问题是您正在更新self.base_fields,这是的字段dict,而不是self.fields,它是实例上的副本。

由于您在更新fields时已创建base_fields,因此它使用旧版本的选项;下次渲染页面时,它将使用此次创建的版本。