覆盖Django ModelForm中的ChoiceField小部件,无需重新指定选项 [英] Override ChoiceField widget in Django ModelForm without re-specifying choices

查看:129
本文介绍了覆盖Django ModelForm中的ChoiceField小部件,无需重新指定选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试覆盖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 的小部件就像这样消除了 form.fields ['icon']。选项属性继承自模型,并将其设置为 [] ,因为Django。如果我从表单中删除图标字段定义,则会保留选项 - 但是当然,该窗口小部件默认为选择



(生成模型字段选项的函数不可用表单代码访问。)



我到目前为止最好的是将图标表单字段定义更改为

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

但这是笨重的,我宁愿自动传递选项,就像内向 ChoiceField 行为一样。 (我尝试将 ChoiceField 子类化为 IconChoiceField 这是相同的,但默认的小部件 IconPicker 但Django将它转换回一个 TypedChoiceField 与默认的选择小部件因为此问题。)



有没有办法覆盖 ChoiceField 小部件属性,同时保留继承选择的行为从模型?

解决方案

我认为你失去在你的模型中指定的选择的原因,即将它设置为 [] 不是因为Django,而是因为您使用行 icon = models.ChoiceField(widget = IconPicker)覆盖图标字段请注意,如果您使用的是模型窗体,则不必在init处覆盖窗口小部件,而应该在窗体中指定该窗口小部件。元组字典中的Meta类。

  class UserGroupForm(forms.ModelForm):

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

为了覆盖选项,您可以简单地执行 self.fields ['icon']。choices = UserGroupForm.ICON_CHOICES ,但在这种情况下,我不认为你需要重写选择。


I am trying to override the default widget for a Django ChoiceField while preserving the choices generated in the model. Here is the relevant part of my model:

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

And of my form:

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

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

Overriding the ChoiceField's widget like this clobbers the form.fields['icon'].choices attribute normally inherited from the model and sets it to [] because Django. If I remove the icon field definition from the form, the choices are preserved - but of course the widget defaults to a Select.

(The function which generates the choices for the model field is not accessible from the form code unfortunately.)

The best I have come up with so far for is to change the icon form field definition to

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

but this is clunky and I would rather have the choices automatically passed on as in the introspected ChoiceField behavior. (I tried subclassing ChoiceField to IconChoiceField which was identical but for a default widget of IconPicker but Django converts it back to a TypedChoiceField with the default Select widget because of this issue.)

Is there a way to override the ChoiceField's widget attribute while preserving the behavior of inheriting choices from the model?

解决方案

I think the reason you are losing the choices you specified in your model i.e. "sets it to []" is not "because Django", but because you override the icon field with the line icon = models.ChoiceField(widget=IconPicker)

Please note that if you are using a modelform then it is not necessary to override the widget at init, instead the widget should be specified in the Meta class in the widgets dictionary.

class UserGroupForm(forms.ModelForm):

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

As for overriding the choices you can simply do self.fields['icon'].choices = UserGroupForm.ICON_CHOICES, but I don't think you need to override choices in this instance.

这篇关于覆盖Django ModelForm中的ChoiceField小部件,无需重新指定选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆