2013-03-13 67 views
2

下面的代碼:爲什麼Django在這個表單驗證上拋出一個KeyError?

... 

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 

最令人不安的是,它的工作原理(提交併在數據庫中仍然存在)在幾乎所有情況。當我寫在VIDEO_URL場虛擬文本,如「aeuchah」實在不行,而是它拋出:

Exception Type: KeyError 
Exception Value:  
'video_url' 

我重新閱讀我clean_video_url方法,去看看有什麼變量是用調試工具,如pdb.set_trace,但我找不到問題。

UPDATE馬呂斯Grigaitis和達維德R.說,所有的單個字段的方法完成後的清潔方法被調用。 clean_video_url引發了一個ValidationError並且什麼也沒有返回,所以clean方法沒有發現任何東西可用,並引發了一個KeyError。

+0

你可以顯示完整的追溯? – 2013-03-13 21:06:23

+2

我今天早些時候回答了這個完全相同的問題:http://stackoverflow.com/questions/15382914/ – 2013-03-13 21:13:39

+0

你說得對,那確實是問題所在。我明白表單驗證如何更好地發揮作用。謝謝。 – user1011444 2013-03-13 21:33:39

回答

3

在使用clean()方法之前,您應該始終檢查該密鑰是否存在於cleaned_data中。如果以前的驗證未通過,則不保證該值存在於cleared_data數組中。

文檔:https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

通過被稱爲形式的clean()方法,所有的個體場清潔方法將已經運行(前兩節)的時候,所以self.cleaned_data將與任何數據填充迄今存活下來。所以你還需要記住允許你想要驗證的字段可能沒有在最初的單個字段檢查中存活。

+0

感謝您的快速回答,解決了我一直存在的問題。我檢查了clean_video_url,但不是乾淨的方法。 – user1011444 2013-03-13 21:32:52

相關問題