Django мультивиджет и проблема проверки

Я создал подклассы для нескольких виджетов, чтобы создать ползунок диапазона HTML5, синхронизированный с полем NumberInput, используя этот код:

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': ['Введите число.']}]

Только виджеты работают хорошо, и форма правильно связана. Но не в мультивиджете. Что я делаю неправильно? я добавил

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])]

но это все еще не работает.

Спасибо за вашу помощь.

1 ответ

Я нашел решение: мне нужно было реализовать

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() возвращает список значений, соответствующих каждому виджету. Это целесообразно при использовании MultiWidget с MultiValueField, но, поскольку мы хотим использовать этот виджет с TextField, который принимает одно значение, мы переопределили этот метод, чтобы объединить данные всех подвиджетов в значение.

Другие вопросы по тегам