Reputation: 1399
Here's the code:
...
class Meta:
model = Card
def clean_video_url(self):
video_url = self.cleaned_data['video_url']
if video_url != '' and len(video_url) != YOUTUBE_VIDEO_URL_LENGTH:
pos = string.find(video_url, YOUTUBE_VIDEO_URL_IDENTIFIER)
identifier_length = len(YOUTUBE_VIDEO_URL_IDENTIFIER)
if pos == -1:
raise forms.ValidationError(_('youtube-url-not-valid'))
video_url = video_url[pos+identifier_length:pos+identifier_length+YOUTUBE_VIDEO_URL_LENGTH]
return video_url
...
def clean(self):
video_url = self.cleaned_data['video_url']
field1 = self.cleaned_data['field1']
if video_url == '' and field1 == '':
raise forms.ValidationError(_('must-fill-video-url-or-front'))
return self.cleaned_data
The most disturbing thing is that it works (submits and persists in the database) in almost all situations. It doesn't work when I write dummy text like 'aeuchah' in the video_url field, but instead it throws:
Exception Type: KeyError
Exception Value:
'video_url'
I re-read my clean_video_url method and went to see what the variables were with a debug tool like pdb.set_trace, but I can't find the problem.
UPDATE: As Marius Grigaitis and Davide R. said, the clean method is called after all the individual field methods are done. clean_video_url raised a ValidationError and returned nothing, so the clean method found nothing to work with and raised a KeyError.
Upvotes: 3
Views: 1262
Reputation: 2520
You should always check that key exists in cleaned_data
before using it in clean()
method. You're not guaranteed that value is present in cleaned_data array if previous validations has not passed.
Documentation: https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other
By the time the form’s
clean()
method is called, all the individual field clean methods will have been run (the previous two sections), so self.cleaned_data will be populated with any data that has survived so far. So you also need to remember to allow for the fact that the fields you are wanting to validate might not have survived the initial individual field checks.
Upvotes: 4