Подтвердить что ты не робот

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()? Или я должен делать это по-другому?

4b9b3361

Ответ 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(). Просто прочитайте раздел" Очистка по умолчанию для поля формы и его пример