django - как обработать / очистить поле перед проверкой - PullRequest
25 голосов
/ 06 февраля 2011

У меня есть форма, которую нужно проверять только после ее очистки.

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

Ответы [ 4 ]

34 голосов
/ 06 февраля 2011

Я думаю, что процесс проверки формы (и ее правильный порядок) действительно хорошо документирован.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 не нарушено.Таким образом, изменение данных впоследствии никак не повлияет.

Решение состоит в том, чтобы поднять 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 голосов
/ 03 июля 2013

Кроме того, когда is_valid() возвращает False, вы можете проверить почему, печатая self.errors внутри формы.

, если вы смотрите код is_valid(), это проверяет форму is_bound а self.errors пусто

0 голосов
/ 27 февраля 2019

Вы можете перезаписать CharField:

class CustomCharField(forms.CharField):
    def clean(self, value):
        return super().clean(value.replace('a', ''))

Тогда вы можете использовать его в форме

class ContactForm(forms.Form):
    message = CustomCharField(widget=forms.Textarea)
0 голосов
/ 28 декабря 2016

Просто добавляю в Райнер Гереке.

Когда в форме вызывается метод is_valid (), метод MultiEmailField.clean () будет запущен как часть процесса очистки и, в свою очередь, вызовет пользовательские методы to_python () и validate (). Просто прочитайте часть «Очистка поля формы по умолчанию» и ее пример

...