python / intermediate
Snippet
Django Form Custom Validation with clean Methods
Django forms provide two levels of validation: field-level clean methods and object-level clean(). Field-specific clean_<fieldname> methods run automatically after single-field validation. The clean() method performs cross-field validation after all field-level checks pass. This layered approach ensures data consistency and provides clear error messages.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from django import formsfrom django.core.exceptions import ValidationErrorclass BookingForm(forms.Form):check_in = forms.DateField(label='Check-in Date')check_out = forms.DateField(label='Check-out Date')guests = forms.IntegerField(min_value=1, max_value=10)room_type = forms.ChoiceField(choices=[('standard', 'Standard'),('deluxe', 'Deluxe'),('suite', 'Suite')])def clean_check_out(self):check_in = self.cleaned_data.get('check_in')check_out = self.cleaned_data.get('check_out')if check_in and check_out:if check_out <= check_in:raise ValidationError('Check-out must be after check-in date')delta = check_out - check_inif delta.days > 30:raise ValidationError('Maximum stay is 30 nights')return check_outdef clean(self):cleaned_data = super().clean()check_in = cleaned_data.get('check_in')room_type = cleaned_data.get('room_type')if check_in and check_in < forms.DateField().to_python(forms.DateField().initial):raise ValidationError('Cannot book dates in the past')if room_type == 'suite' and cleaned_data.get('guests', 0) > 4:raise ValidationError('Suite rooms accommodate maximum 4 guests')return cleaned_data
django
Breakdown
1
class BookingForm(forms.Form):
Define a Django Form class inheriting from forms.Form
2
check_in = forms.DateField(...)
Date field for check-in date input
3
def clean_check_out(self):
Field-specific validation method for check_out field
4
check_in = self.cleaned_data.get('check_in')
Access other cleaned fields to compare dates
5
if check_out <= check_in:
Business rule: check-out must be after check-in
6
raise ValidationError(...)
Django automatically associates error with the field
7
def clean(self):
Cross-field validation method called after all field-level cleans
8
cleaned_data = super().clean()
Call parent clean() to ensure all fields are already cleaned
9
return cleaned_data
Must return the cleaned_data dictionary