0

我一直在子类化 multiwidget 以使用以下代码创建与 NumberInput 字段同步的 HTML5 范围滑块:

class SplitRangeNumberWidget(MultiWidget):
    def __init__(self):
        widgets = (
                 forms.NumberInput(attrs={'type':'range',
                                             'onchange':'this.nextElementSibling.value=this.value',
                                             'oninput':'this.nextElementSibling.value=this.value',
                                             'step':'any',
                                             'min':0,
                                             'max':1}),

                   forms.NumberInput(attrs={'step':'any',
                                            'onchange':'this.previousElementSibling.value=this.value',
                                            'oninput':'this.previousElementSibling.value=this.value',})
                   )
        super(SplitRangeNumberWidget, self).__init__(widgets)

    def decompress(self, value):
        if value:
            return [value, value]
        return [None, None]

当我实例化它并以如下形式使用它时:

class ParameterForm(forms.ModelForm):
    class Meta:
        model = Parameter
        fields = ['name','value','min_value','max_value']
        widgets = {'value':SplitRangeNumberWidget()}

,小部件工作正常:更改滑块或数字输入确实会更改其他字段。但是,在执行 POST 时,表单无法验证,并且我在 form.errors 中收到此错误(对于 3 个参数):

[{'value': ['输入一个数字。']}, {'value': ['输入一个数字。']}, {'value': ['输入一个数字。']}]

单独的小部件运行良好并且表单被正确绑定。但不是在multiwidget中。我究竟做错了什么?我添加了

def value_from_datadict(self, data, files, name):
    num = [widget.value_from_datadict(data, files, name + '_%s' % i)
        for i, widget in enumerate(self.widgets)]
    return [float(num[0]), float(num[1])]

但这仍然不起作用。

谢谢你的帮助。

4

1 回答 1

0

我找到了解决方案:我需要实施

def value_from_datadict(self, data, files, name):
        value_list = [widget.value_from_datadict(data, files, name + '_%s' % i)
                      for i, widget in enumerate(self.widgets)]    
        try:
            value = value_list[0]
        except ValueError:
            return None
        else:
            return value

解释文档: value_from_datadict() 的默认实现返回与每个 Widget 对应的值列表。这在使用带有 MultiValueField 的 MultiWidget 时是合适的,但由于我们希望将此小部件与采用单个值的 TextField 一起使用,因此我们重写了此方法以将所有子小部件的数据组合成一个值。

于 2017-01-10T13:45:29.330 回答