Метод clean
Метод clean применяется к классу формы и позволяет
выполнять валидацию данных, которые требуют проверки
связи между несколькими полями или сложной логики.
Метод вызывается автоматически в процессе валидации
формы после выполнения стандартных валидаторов полей
и метода clean_<fieldname> для каждого поля.
В методе clean можно получить доступ к уже
очищенным данным из словаря cleaned_data и
вернуть этот же словарь после проверки. Если данные
не проходят валидацию, метод должен выбрасывать
исключение ValidationError.
Синтаксис
from django import forms
from django.core.exceptions import ValidationError
class MyForm(forms.Form):
# поля формы
def clean(self):
cleaned_data = super().clean()
# валидация данных
return cleaned_data
Пример
Создадим форму регистрации, где необходимо проверить, что пароль и подтверждение пароля совпадают:
from django import forms
from django.core.exceptions import ValidationError
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
confirm_password = cleaned_data.get('confirm_password')
if password and confirm_password and password != confirm_password:
raise ValidationError('Passwords do not match')
return cleaned_data
Пример
Рассмотрим валидацию формы, где нужно проверить, что возраст пользователя находится в допустимом диапазоне в зависимости от его роли:
from django import forms
from django.core.exceptions import ValidationError
class UserForm(forms.Form):
name = forms.CharField(max_length=100)
age = forms.IntegerField(min_value=0, max_value=120)
role = forms.ChoiceField(choices=[
('student', 'Student'),
('teacher', 'Teacher'),
('admin', 'Administrator')
])
def clean(self):
cleaned_data = super().clean()
age = cleaned_data.get('age')
role = cleaned_data.get('role')
if role == 'student' and age < 6:
raise ValidationError('Student must be at least 6 years old')
if role == 'teacher' and age < 18:
raise ValidationError('Teacher must be at least 18 years old')
if role == 'admin' and age < 21:
raise ValidationError('Administrator must be at least 21 years old')
return cleaned_data
Пример использования формы с обработкой ошибок:
from django.shortcuts import render
from .forms import UserForm
def create_user(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
# обработка данных
return render(request, 'success.html')
else:
form = UserForm()
return render(request, 'user_form.html', {'form': form})
Пример
Валидация с использованием нескольких полей для проверки даты: начало события не может быть позже его окончания:
from django import forms
from django.core.exceptions import ValidationError
from datetime import date
class EventForm(forms.Form):
name = forms.CharField(max_length=200)
start_date = forms.DateField()
end_date = forms.DateField()
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date and end_date and start_date > end_date:
raise ValidationError('Start date cannot be later than end date')
return cleaned_data
Вывод формы в шаблоне:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create event</button>
</form>
Результат валидации при неправильных данных:
"Form errors: {'__all__': ['Start date cannot be later than end date']}"
Смотрите также
-
метод
is_valid,
который запускает валидацию формы -
атрибут
cleaned_data,
который содержит очищенные данные формы -
атрибут
errors,
который содержит ошибки валидации -
метод
add_error,
который добавляет ошибки к конкретным полям