3 марта 2009 г.

Django. Валидация формсетов. Часть вторая

При использовании двух формсетов в одном виде возникает следующая проблема валидации:
1. Валидация формсета проходит следующим образом:
а)Валидируются все формы, входящие в рамки:
self._total_form_count = self.management_form.cleaned_data[TOTAL_FORM_COUNT]
б)экстра-формы, в которых нет вообще никаких данных игнорируются.
2. В связи с синхронным использованием двух формсетов может возникнуть следующая проблема:

У одного формсета валидируются, например, 1,2 и 5 форма, а у другого только 1,2, в связи с тем что у второго формсета 5 форма пустая.

Вот эту проблему и попытаемся сегодня решить.

Начало функции, отвечающей за валидацию вормы (валидация формсетов - это просто валидация каждой формы в формсете)

208 def full_clean(self):
209 """
210 Cleans all of self.data and populates self._errors and
211 self.cleaned_data.
212 """
213 self._errors = ErrorDict()
214 if not self.is_bound: # Stop further processing.
215 return
216 self.cleaned_data = {}
217 # If the form is permitted to be empty, and none of the form data has
218 # changed from the initial data, short circuit any validation.
219 if self.empty_permitted and not self.has_changed():
220 return

Как написано в комментариях в коде - если форме разрешено быть пустой, прекращаем всякую валидацию. Значит, наша задача, привести свойство empty_permitted или метод has_changed() для каждой формы в каждом формсете к единому синхронному виду.

Переопределяем функцию has_changed(), в обоих классах, в котором мы описываем формы, использующиеся в формсетах:

def has_changed(self):
"""
Returns True if data differs from initial.
"""
if hasattr(self, 'is_change'):#проверяем, если наш динамический атрибут is_change
return True
else:
return bool(self.changed_data)


Дальше ясно - создаем динамический новый атрибут для объекта формы в случае, если в формсетах две синхронные формы имеют разные зачения has_changed(), в итоге, они станут иметь одинаковые. Ес-но, это надо проделать до валидации формсетов.

Комментариев нет:

Отправить комментарий