6

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

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

效果是:

在此处输入图像描述

虽然这是一个不错的功能,但如果我可以像(在伪代码中)那样动态添加它会更有用:

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

我试图像这样覆盖表单的初始化:

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方法中放置断点时才有效。似乎涉及一些时间问题。

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

4

2 回答 2

12

问题在于:

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

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

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

...它完美无缺

于 2013-03-14T09:13:23.143 回答
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)
于 2013-03-13T10:40:34.743 回答