动态修改Django中的表单小部件

时间:2013-03-13 10:25:56

标签: django django-forms

我的Django应用程序使用Django Suit作为主题Django管理应用程序的工具。 Suit可以做的事情之一是追加和预置元素以形成小部件,如:

class PropertyForm(ModelForm):
    class Meta:
        model = Property
        widgets = {
            'amount': EnclosedInput(prepend = "GBP"),
        }

效果是:

enter image description here

虽然这是一个很好的功能,但如果我可以动态添加它(如伪代码)会更有用:

'amount': EnclosedInput(prepend = my_model_instance.currency)

我试图像这样覆盖表单的init:

class PropertyForm(ModelForm):

    def __init__(self, *args, **kwargs):
        inst = kwargs["instance"]
        self._meta.widgets["amount"] = EnclosedInput(prepend = inst.currency)
        super(PropertyForm, self).__init__(*args, **kwargs)

奇怪的是,只有在 init 方法中放置断点时才有效。看起来有一些时间问题。

所以我的问题是实现这一目标的最佳方式(如果可以的话)是什么?

2 个答案:

答案 0 :(得分:10)

问题在于:

self._meta.widgets["amount"] = EnclosedInput(prepend = inst.currency)

事实证明_meta正在被缓存。当我将上面的行更改为(这也是一个更好的解决方案,因为_meta可能是私有的):

self.fields['amount'].widget = EnclosedInput(prepend = inst.currency)

......它完美无瑕地运作

答案 1 :(得分:1)

一种简单的方法是在每次需要时配置表单类:

def make_property_form(currency):
    class PropertyForm(forms.Form):
        # ...
        widgets = {
            'amount': EnclosedInput(prepend=currency),
        }
    return PropertyForm

def view_that_uses_my_form(request):
    # ...
    form_class = make_property_form(model.currency)
    form = form_class(the_usual_form_initialization)