Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Django throw a KeyError on this form validation?

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.

like image 325
user1011444 Avatar asked Jul 03 '26 02:07

user1011444


1 Answers

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.

like image 199
Marius Grigaitis Avatar answered Jul 04 '26 16:07

Marius Grigaitis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!