2011-06-01 98 views
17

我正在試驗一個允許用戶上傳音頻文件的網站。我已經閱讀了所有可以得到我的手的文檔,但找不到有關驗證文件的更多信息。Django(音頻)文件驗證

這裏總共有newb(從來沒有做過任何之前的任何類型的文件驗證)並試圖弄清楚這一點。有人能握住我的手,告訴我我需要知道什麼嗎?

一如既往,先謝謝您。

+0

你是什麼意思驗證?您是否想驗證用戶是否上傳了任何舊文件?或者驗證該文件實際上是一個音頻文件?或者進一步驗證音頻文件的特定屬性,即它的長度? – 2011-06-01 00:08:41

+1

我的意思是說(從django文檔):「請注意,無論何時處理上傳的文件,您都應該密切關注您上傳的文件的位置以及它們的類型,以避免安全漏洞。驗證所有上傳的文件,以便確保文件是您認爲的文件。例如,如果您盲目地讓某人上傳文件(如果沒有進行驗證)到Web服務器文檔根目錄中的目錄中,則有人可以上傳CGI或PHP腳本,並通過訪問您網站上的URL來執行該腳本。 「 – 2011-06-01 00:51:46

+0

好的,你有沒有文件上傳工作開始? – 2011-06-01 00:53:38

回答

23

您想在文件寫入磁盤之前驗證文件。當您上傳文件時,表單會得到驗證,然後上傳的文件將傳遞給處理器/方法,該處理器/方法會處理實際寫入服務器磁盤的操作。因此,在這兩個操作之間,要進行一些自定義的驗證,以確保它是一個有效的音頻文件

,你可以:

  • 檢查,如果該文件是小於一定尺寸(好的做法)
  • 然後檢查提交的文件具有一定的內容類型(例如音頻文件)
    • 這是非常無用的人可以很容易地欺騙它
  • 然後檢查該文件在一定的擴展名結尾(或擴展)
    • 這也沒什麼用
  • 嘗試讀取這個文件,看看它實際上是音頻

(我的天堂」噸測試此代碼)

models.py

class UserSong(models.Model): 
    title = models.CharField(max_length=100) 
    audio_file = models.FileField() 

forms.py

class UserSongForm(forms.ModelForm): 
    # Add some custom validation to our file field 
    def clean_audio_file(self): 
     file = self.cleaned_data.get('audio_file',False): 
     if file: 
      if file._size > 4*1024*1024: 
        raise ValidationError("Audio file too large (> 4mb)") 
      if not file.content-type in ["audio/mpeg","audio/..."]: 
        raise ValidationError("Content-Type is not mpeg") 
      if not os.path.splitext(file.name)[1] in [".mp3",".wav" ...]: 
        raise ValidationError("Doesn't have proper extension") 
      # Here we need to now to read the file and see if it's actually 
      # a valid audio file. I don't know what the best library is to 
      # to do this 
      if not some_lib.is_audio(file.content): 
        raise ValidationError("Not a valid audio file") 
      return file 
     else: 
      raise ValidationError("Couldn't read uploaded file") 

views.py 從utils的進口handle_uploaded_file

def upload_file(request): 
    if request.method == 'POST': 
     form = UserSongForm(request.POST, request.FILES) 
     if form.is_valid(): 
      # If we are here, the above file validation has completed 
      # so we can now write the file to disk 
      handle_uploaded_file(request.FILES['file']) 
      return HttpResponseRedirect('/success/url/') 
    else: 
     form = UploadFileForm() 
    return render_to_response('upload.html', {'form': form}) 

utils.py

# from django's docs 
def handle_uploaded_file(f): 
    ext = os.path.splitext(f.name)[1] 
    destination = open('some/file/name%s'%(ext), 'wb+') 
    for chunk in f.chunks(): 
     destination.write(chunk) 
    destination.close() 

https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#file-uploads https://docs.djangoproject.com/en/dev/ref/forms/fields/#filefield https://docs.djangoproject.com/en/dev/ref/files/file/#django.core.files.File

+1

這是一個完整的Django文件驗證答案。基本上,你總是需要提供一些庫來解析內容頭或打開文件來確定你收到的內容是否是你期望的內容,這就是'(bool)some_lib.is_audio(file.content)'的作用,這是你需要找到一個合適的實現。 – 2011-06-01 08:03:57

+0

哇!謝謝,謝謝,謝謝,這超出了我的期望。Pastylegs,你是我的英雄! – 2011-06-01 17:32:00

+0

Filip,足以解析頭文件嗎?UploadedFile.content_type()已經在做這個了。 – 2011-07-02 17:56:39