Django, form.is_valid() Что он проверяет?

Я не использую форму models.form Я получил и сохранил каждый элемент request.POST и request.FILES Я буду делать свою функцию валидации. Поэтому мне интересно, какую валидацию она делает. (например, вход пустой и т.д.)

Ручная обработка request.POST и request.FILES - оченьплохая идея: данные могут быть "подделаны", а спецификации HTML о том, как строится запрос с <form>, имеют некоторые особенности. Например, если флажок <input type="checkbox" name="somename"> установлен не установлен , то он не появляется в запросе, тогда как если он установлен, то появляется в запросе без значения.

Первая проблема заключается в том, что не все поля формы будут отображаться в request.POST, что само по себе не является проблемой: некоторые поля могут быть необязательными. Таким образом, форма Django будет проверять все поля, которые являются обязательными, если значение появляется в request.POST и request.FILES.

Next the form will start cleaning the data. This means that it converts the data, which are all strings, to a more suitable datatype. For example for a DateField, it will try to convert this to a date object. It will normally try all formats in the DATE_INPUT_FORMAT setting [Django-doc], but you can customize that when you construct a DateField to thus use a different format for that specific field. Some fields, like a BooleanField will for example look if the field is indeed in the request.POST and then return True and otherwise False, so this is not just a simple mapping of the value in request.POST, since that value might not be there.

Очистка не только отображает строки на соответствующие объекты Python, она также может выполнять некоторую (небольшую) постобработку этих полей. Например, CharField по умолчанию trim строку, и таким образом удалит ведущие и последующие пробелы, в то время как ModelChoiceField выберет соответствующий объект модели для данного первичного ключа из базы данных. Поле формы также имеет список пустых значений: значения, которые считаются пустыми. Например, для CharField можно установить '/' как пустое значение. Тогда косая черта будет рассматриваться как пустое поле.

Можно создавать дополнительные поля формы, помимо тех, которые определены, и это означает, что легко построить, например, EANField, в котором вы реализуете очистку один раз, но это означает, что вам нужно делать это для каждого представления. Таким образом, поля формы используются для того, чтобы сделать очистку более многоразовой путем внедрения процесса очистки в поле.

Next in line are validations on the form fields. While a text field in HTML can have a <input type="text" minlength="6" maxlength="24">, you can nevery rely on what the browser will post as values: indeed POST requests can be forged, so while the HTML form might intent to prevent people from picking a username with less than six characters, or more than twenty-four characters, you can not be sure that this will be the case in the POST request. A form field can be passed validators=… [Django-doc]: a set of callables that raise a validation error in case the item is not valid. For example for a CharField, if you pass a value for the min_length=… and/or max_length=… validators, it will thus check these. It will add all ValidationErrors to a list, which is often cumbersome to implement in a view: most views that validate data will check a certain condition, for example the minimum length of the characters for a password, and if that fails, report an error, whereas with a Form, it can also add an extra error that you should use at least one digit. The form will do that for all form fields, and thus construct a dictionary mapping the name of the fields to a list of errors.

Если все поля формы успешно вернут валидность данных, то форма создаст атрибут .cleaned_data [Django-doc], который сопоставляет имена полей с соответствующим значением, которое было очищено этим полем формы. Однако можно добавить дополнительную очистку и валидацию к Form.

Затем существуют валидации на уровне самой формы. Если вы хотите слегка настроить форму, то сформируйте поле с именем field_name, вы можете реализовать метод clean_field_name. Этот метод может получить доступ к словарю .cleaned_data, затем выполнить дополнительную проверку этого поля и поднять сообщение ValidationError, а также "очистить" функцию, например, вернув объект другого типа или выполнив некоторую постобработку возвращаемых данных. Таким образом, Form соберет эти значения и обновит словарь этими очищенными значениями. Кроме того, если метод вызовет ошибку ValidationError, она будет добавлена к .errors для этого конкретного поля.

После этого форма вызовет метод .clean() [Django-doc]. Это выполнит очистку всей формы. Действительно, теперь, когда все поля очищены по отдельности, все еще может оказаться, что есть ошибки относительно комбинации полей. Например, совпадают ли два поля пароля. Обычно метод clean таким образом работает с множеством полей в атрибуте .cleaned_data и возвращает, например, словарь или другой объект. Если вы вызовете здесь ошибку ValidationError, то она будет помещена в .errors под ключом '__all__', поскольку это не связано с конкретным полем.

For a ModelForm [Django-doc], the validation is not over yet. Indeed, the model itself can still have some validation. It will update the instance wrapped in the form with the values of the cleaned data, and call the .full_clean() method [Django-doc] on the instance, and later also call the .validate_unique(…) method [Django-doc] to validate that for fields that should be unique (have unique=True), these are indeed unique. That last task is often more complicated than it looks at first sight, since if the instance is edited in the form, the check in the database, should exclude the current instance you are editing.

Только после всех этих проверок Form или ModelForm примет изменение, и тогда .is_valid() вернет True. Если на одном из шагов таким образом произойдет сбой, то ошибка будет добавлена в .errors, и таким образом .errors попытается построить словарь, который попытается сообщить обо всех проблемах с данными. Это полезно, если вы переделали форму, так как тогда ошибки можно поместить рядом с соответствующим полем, и пользователь таким образом получит обратную связь о всех проблемах с данными, а не о первой, с которой столкнулась форма, так как это может привести к множеству попыток исправить форму.

Подведем итог: в Form существует много логики для проверки и очистки данных. Попытка реализовать это в представлении - распространенная ошибка. Правильно сделать это в представлении громоздко, но и не очень гибко: если вы захотите добавить дополнительный валидатор для пароля, например, это потребует много работы, особенно если вы хотите сделать это в нескольких представлениях. Формы создаются для работы с повторно используемыми компонентами, такими как поля, валидаторы, проверки на уникальность и т.д. Он также достаточно надежен, поскольку нацелен на проверку данных запроса, которые могут быть подделаны, и поэтому не были должным образом проверены HTML-атрибутами.

Вернуться на верх