【问题标题】:django - how can I access the form field from inside a custom widgetdjango - 如何从自定义小部件内部访问表单字段
【发布时间】:2010-11-16 15:06:57
【问题描述】:

以下类继承自 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 参数。我该怎么做?

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    虽然不是解决您的问题所必需的,但有时访问表单或表单域确实很有用。在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
    

    【讨论】:

    • 从 Form 类内部,您可以通过 self.instance 访问 Model 实例。请记住,添加/创建新对象时,实例会相当空白。
    • 在最近的版本中,您可以通过render(self, name, value, attrs = None)中的value.instance访问实例
    【解决方案2】:

    从技术上讲,小部件不必与字段有直接关系,因此您不必这样做。

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

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

    另外,我不确定将其留在 attrs 中是否是个好主意 - &lt;TextArea&gt; 将使用无效的 max_length 参数呈现。或许您应该改为pop()关闭它?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-03
      • 2017-09-03
      • 2012-10-29
      • 2013-04-03
      • 2011-03-29
      • 2012-01-18
      • 2014-06-24
      • 1970-01-01
      相关资源
      最近更新 更多