django - 如何从自定义小部件中访问表单字段

时间:2009-08-04 09:48:01

标签: django django-forms

以下类继承自 Textarea 小部件,并提供javascript代码,显示用户可以在textarea中输入的字符数。

class TextAreaWithCharCounter(forms.Textarea):

    class Media:
        js = ('js/jquery.charcounter.js',)

    def render(self, name, value, attrs = None):
        id = attrs['id']
        max_length = self.attrs.get('max_length', 200)
        output = super(TextAreaWithCharCounter, self).render(name, value, attrs)
        output += mark_safe(u'''
                        <script type="text/javascript">
                        $("#%s").charCounter(%d, {classname:"charcounter"});
                        </script>'''%(id, max_length))        
        return output

表格代码的相关部分如下:

class MyForm(forms.Form):
    foo = forms.CharField(max_length = 200, widget = TextAreaWithCharCounter(attrs={'max_length':200}))
    ...

您可以看到我两次传递 max_length 参数,一个用于字段,另一个用于窗口小部件。更好的方法是从窗口小部件内部访问表单字段并获取其max_length属性,以便窗口小部件不需要max_length参数。我怎么能这样做?

2 个答案:

答案 0 :(得分:12)

虽然不是解决问题所必需的,但访问表单或表单字段有时可能确实有用。请参阅another question的完整答案,但简而言之,您可以手动将表单或字段绑定到窗口小部件__init__

class MyForm(forms.ModelForm):
    foo = forms.ModelChoiceField(Foo.objects, widget=CustomWidget())

    class Meta:
        model = Bar

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['foo'].widget.form_instance = self

答案 1 :(得分:3)

从技术上讲,Widget不必与Field有直接关系,所以你不要这样做。

查看source of CharField,您可以看到它有widget_attrs方法,可自动将maxlength属性添加到TextInput / PasswordInput字段。< / p>

我建议您使用自定义字段覆盖此方法并为自定义窗口小部件添加属性。

另外,我不确定将它留在attrs中是个好主意 - <TextArea>将使用无效的max_length参数进行渲染。也许你应该pop()来代替它?