Django - как обработать/очистить поле перед проверкой
У меня есть форма, которая должна быть проверена только после ее очистки.
Что происходит при запуске form.is_valid()
? Очищается ли форма, а затем очищенная версия формы подтверждена?
Поведение, которое я получаю в данный момент, заключается в том, что если мое поле не проходит проверку перед очисткой, даже если очистка сделает его, is_valid()
возвращает False
.
Я что-то делаю неправильно?
код:
# View
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea, max_length=5)
def clean_message(self):
message = self.cleaned_data['message']
return message.replace('a', '') # remove all "a"s from message
def contact(request):
if request.method == 'POST':
if form.is_valid():
return HttpResponseRedirect('/contact/on_success/')
else:
return HttpResponseRedirect('/contact/on_failure/')
Я хочу, чтобы form.is_valid()
возвращал True
, если сообщение имеет менее 5 символов НЕ, включая a
!
Можно ли запустить clean_<fieldname>()
после to_python()
, но до run_validators()
? Или я должен делать это по-другому?
Ответы
Ответ 1
Я думаю, что процесс проверки формы (и ее правильный порядок) действительно хорошо документирован. http://docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation
Не могли бы вы поделиться каким-то кодом? Существует метод clean
на каждом поле формы, отвечающий за запуск to_python
, validate
и run_validators
(в этом порядке). to_python
принимает исходное значение виджета, принуждая его к типу python, validate
берет принудительное значение и запускает проверку, зависящую от поля.
Ответ обновлен относительно кода
clean_message
вызывается после того, как все остальные проверки выполнялись как to_python
, validate
и, самое главное, run_validators
. Я думаю, что последний метод проверяет, что ограничение max_length
не нарушено. Таким образом, вы не изменяете данные после этого.
Решение состоит в том, чтобы поднять a ValidationError
здесь. Удаление max_length
позволит избежать проверки на входной длине.
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
message = message.replace('a', '') # remove all "a"s from message
if len(message) >= 5:
raise ValidationError('Too many characters ...')
return message
Ответ 2
В качестве дополнительного, когда is_valid()
return False
, вы можете проверить, почему, напечатав self.errors
внутри формы.
если вы смотрите код is_valid()
, это проверяет форму is_bound
и self.errors
пуст
Ответ 3
Просто добавив к Рейнеру Гереке.
Когда в форме вызывается метод is_valid(), метод MultiEmailField.clean() будет запущен как часть процесса очистки, и он, в свою очередь, вызовет пользовательские методы to_python() и validate().
Просто прочитайте раздел" Очистка по умолчанию для поля формы и его пример