Im reading a book called "Web development with Django" which I like a lot. One of the things which gets taught there is that you can change a value coming from the form. I have tested raising errors (validation error from django core) which works fine. But I can't get the "clean_name" function to work on the input. The function is located at the bottom.
I hope someone here knows what im doing wrong :)
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
def validate_regnr(value):
if value[:3].upper() != value[:3]:
raise ValidationError(f'{value} is not correct')
class BookingForm(forms.Form):
SERVICES = (
('1', 'Årsservice'),
('2', 'Storservice'),
('3', 'Bromsservice')
)
regnr = forms.CharField(min_length=6, max_length=6, validators=[validate_regnr])
service = forms.ChoiceField(choices=SERVICES)
name = forms.CharField(max_length=255)
tel = forms.CharField(max_length=20)
email = forms.EmailField()
datetime = forms.DateTimeField(widget=widgets.DateInput(attrs={'type': 'datetime-local'}))
kommentar = forms.TextInput()
def clean_name(self):
value = self.cleaned_data['name']
return value.upper()
The order of things is important. First it will run the cleaning and validators defined on the form fields itself. Then it will run the clean_…
methods in the form, and finally, it will run the clean
method.
This thus means that the validator in the field runs before it ever gets to the clean_name
method. Validators defined on the fields thus can not be satisfied with the clean_…
methods, simply because control is never passed to these.
You can however do the cleaning before validating by subclassing the field:
class UppercaseCharField(forms.CharField):
def to_python(self, value):
val = super().to_python(value)
if val is not None:
return val.upper()
and then use that one:
class BookingForm(forms.Form):
# …
regnr = UpperCharField(
min_length=6, max_length=6, validators=[validate_regnr]
)
# no clean_name …