2011-06-25 137 views
4

我可以讓我的文件保存到磁盤,我告訴它,但不能讓它保存到實例,我沒有絲毫的想法爲什麼!爲什麼我的文件不能保存到實例(它保存到磁盤...)?

models.py
class Song(models.Model): 
     name = models.CharField(max_length=50) 
     audio_file = models.FileField(upload_to='uploaded/music/', blank=True) 

views.py
def create_song(request, band_id): 
     if request.method == 'POST': 
      band = Band.objects.get(id=band_id) 
      form = SongForm(request.POST, request.FILES) 
      if form.is_valid(): 
       handle_uploaded_file(request.FILES['audio_file']) 
       form.save() 
       return HttpResponseRedirect(band.get_absolute_url) 
     else: 
      form = SongForm(initial={'band': band_id}) 
     return render_to_response('shows/song_upload.html', {'form': form}, context_instance=RequestContext(request)) 

handle_uploaded_file ​​

song_upload.html(相關部分)

{% block main %} 
    {{band.name}} 
     <form enctype="multipart/form-data" method="post" action="">{% csrf_token %} 
      {{ form.as_p}} 
      <input type="submit" value="Add song" /> 
     </form> 
    {% endblock %} 

forms.py

class SongForm(forms.ModelForm): 
     band = forms.ModelChoiceField(queryset=Band.objects.all(), widget=forms.HiddenInput) 
     def clean_audio_file(self): 
      file = self.cleaned_data.get('audio_file',False) 
      if file: 
       if file._size > 10*1024*1024: 
        raise forms.ValidationError("Audio file too large (> 10mb)") 
       if not file.content_type in ["audio/mp3", "audio/mp4"]: 
        raise forms.ValidationError("Content type is not mp3/mp4") 
       if not os.path.splitext(file.name)[1] in [".mp3", ".mp4"]: 
        raise forms.ValidationErorr("Doesn't have proper extension") 
      else: 
       raise forms.ValidationError("Couldn't read uploaded file") 
     class Meta: 
      model = Song 

該文件是正確的,在媒體/上傳/音樂,但在管理audio_file是空白的,如果我設置空白=假(這是我想做的事情)爲audio_file,我被告知這個字段是必需的。是什麼賦予了??

在此先感謝!在這一段時間裏,文檔對我來說似乎很輕鬆(newb)。

+0

您還應該包含'SongForm'的代碼! –

+0

是的,沒有SongForm,我們不能說出發生了什麼。包括 – Brandon

+0

,我的壞! –

回答

1

clean_audio_file應該爲此特定字段返回已清理的數據,因此您需要爲其添加return file

django's documentation

就像一般領域clean() 方法,上面這種方法應該 返回清理的數據,無論 是否發生了任何變化與否。

+0

銖。這就是我沒有仔細閱讀的結果......當我花時間幫助有問題的人,並且他們沒有仔細閱讀你的答覆時,我知道這一定非常令人沮喪。我真誠的道歉。你在16小時前是對的! –

1

據我所知,你不需要handle_uploaded_file()。您正在使用ModelFormmodels.FileField。它支持upload_to參數,並自動將文件保存到目標。

,它涉及handle_uploaded_file()功能的基本文件上傳從Django文檔example使用Formforms.FileField,並因。

所以,儘量簡單地刪除這一行:

handle_uploaded_file(request.FILES['audio_file']) 
從您的視圖

,並請告訴然後會發生什麼。

編輯:另外,@lazerscience是正確的,你需要在你的clean_audio_file()的末尾添加

return self.cleaned_data 

。 (但是而不是return file,因爲即使只是清理一個字段,您也應該返回整個清理過的數據字典。)

+0

做出了您提到的兩個更改,現在我收到一條錯誤消息:'dict'對象沒有'_committed'屬性。回溯僅包含我自己寫的一行代碼:'form.save()'。如果我刪除form.save()我沒有看到錯誤,但表單不保存!像往常一樣使用文件上傳,谷歌是不是特別有用,我不知道從哪裏開始文檔...預先感謝! –

+0

同樣的錯誤,如果我使用'handle_uploaded_file()'以及 –

+0

這很奇怪。好吧,好像我錯了,@lazerscience確實是對的,只有文件需要從清理方法中返回。 (因爲'_committed'應該是filefield狀態的一部分,但是它不在'cleaned_data'字典中。)嘗試'return file'而不是'return self.cleaned_data'。不過,我仍然確定,'models.FileField'將處理文件存儲。 – Tony