4

我试图覆盖 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's 小部件会破坏form.fields['icon'].choices通常从模型继承的属性并将其设置为[]Django. 如果我icon从表单中删除字段定义,则保留选项 - 但当然小部件默认为Select.

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

到目前为止,我想出的最好的方法是将icon表单字段定义更改为

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

但这很笨拙,我宁愿让选择自动传递,就像内省的ChoiceField行为一样。(我尝试将子类化为相同的子类ChoiceFieldIconChoiceField但对于默认小部件,但由于这个问题IconPicker,Django 将其转换回TypedChoiceField具有默认小部件的 a 。)Select

有没有办法在保留从模型继承的行为的同时覆盖ChoiceField's属性? widgetchoices

4

2 回答 2

7

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

请注意,如果您使用的是模型表单,则无需在初始化时覆盖小部件,而应在小部件字典的 Meta 类中指定小部件。

class UserGroupForm(forms.ModelForm):

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

至于覆盖你可以简单地做的选择self.fields['icon'].choices = UserGroupForm.ICON_CHOICES,但我认为你不需要在这种情况下覆盖选择。

于 2013-10-29T15:32:12.060 回答
5

弄清楚了。UserGroupForm只需要在's中进行一些自我参考__init__

def __init__(self, *args, **kwargs):
    super(UserGroupForm, self).__init__(*args, **kwargs)
    self.fields['icon'].widget = IconPicker(choices=self.fields['icon'].choices)
于 2012-06-16T10:56:59.883 回答