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

sha*_*nyu 9 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

mrt*_*rts 13

虽然不是解决问题所必需的,但有时访问表单或表单字段确实很有用.请参阅另一个问题的完整答案,但简而言之,您可以在表单中手动将表单或字段绑定到窗口小部件__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
Run Code Online (Sandbox Code Playgroud)

  • 在最新版本中,您可以通过`render(self,name,value,attrs = None)中的`value.instance`来访问实例. (2认同)

Smi*_*ris 5

从技术上讲,Widget 不必与 Field 有直接关系,因此您不必这样做。

查看 的来源CharField,可以看到它有一个widget_attrs方法可以自动将maxlength属性添加到TextInput/PasswordInput字段。

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

此外,我不确定将其保留到底attrs是不是一个好主意 -<TextArea>将使用无效max_length参数呈现。也许你应该pop()把它关掉?