在不重新指定选项的情况下覆盖Django ModelForm中的ChoiceField小部件

时间:2012-06-15 21:54:29

标签: django django-forms django-models

我试图覆盖Django ChoiceField的默认小部件,同时保留模型中生成的选项。这是我模型的相关部分:

class UserGroup(models.Model):
    icon = models.CharField(max_length=100, choices=<function call>)

我的形式:

class UserGroupForm(forms.ModelForm):
    icon = models.ChoiceField(widget=IconPicker)

    class Meta:
        model = UserGroup
        fields = [ 'icon', ]

覆盖ChoiceField的小部件,就像这个clobbers一样,form.fields['icon'].choices属性通常从模型继承,并将其设置为[],因为Django。如果我从表单中删除icon字段定义,则会保留选项 - 但当然窗口小部件默认为Select

(遗憾的是,无法从表单代码中访问生成模型字段选项的函数。)

我迄今为止提出的最好的方法是将icon表单字段定义更改为

icon = ChoiceField(choices=UserGroup._meta.get_field_by_name('icon')[0].choices, 
                   widget=IconPicker)

但这很笨重,我宁愿自动传递选项,就像内省ChoiceField行为一样。 (我尝试将ChoiceField子类化为IconChoiceField,这是相同的,但对于IconPicker的默认小部件,但是Django将其转换回TypedChoiceField并使用默认的Select小部件因为this issue。)

有没有办法覆盖ChoiceField的{​​{1}}属性,同时保留从模型继承widget的行为?

2 个答案:

答案 0 :(得分:6)

我认为您丢失在模型中指定的选项的原因,即“将其设置为[]不是“因为Django”,而是因为您覆盖了图标字段icon = models.ChoiceField(widget=IconPicker)

请注意,如果您使用的是modelform,则无需在init处覆盖窗口小部件,而应在窗口小部件字典中的Meta类中指定窗口小部件。

class UserGroupForm(forms.ModelForm):

    class Meta:
        model = UserGroup
        fields = [ 'icon', ]
        widgets = {
            'icon': IconPicker
        }

至于覆盖选项,您只需执行self.fields['icon'].choices = UserGroupForm.ICON_CHOICES,但我认为您不需要在此实例中覆盖选项。

答案 1 :(得分:5)

想出来。在UserGroupForm的{​​{1}} {/ p>中只需要一些自我引用

__init__