2017-03-04 36 views
1

目錄結構現在,在我的數據庫中的每個對象Foo我有相關的文件,該文件被存儲在路徑有以下結構some/example/path/foo/pk/name.txt即成文件,而不暴露在Django

在Django中提供服務的默認方式是在設置中指定MEDIA_ROOTMEDIA_URL。這樣一來,我可以通過訪問localhost:8000/media/foo/1/name.txt和類似的方式爲其他對象訪問與Foo object with id=1相關文件。

但我寧願不暴露給用戶文件的方式存儲在內部(目錄結構,主鍵等),並從localhost:8000/media/mapped_path_to_name.txt爲他們服務。

現在,我能想到的唯一解決方案是創建自定義視圖負責提供文件,並在做路徑映射這個角度提出的邏輯。有沒有更優雅的(簡約)解決這個問題?

+2

有什麼不雅你有什麼建議?似乎是解決此問題的最佳方法。 –

+1

同意。只要我看到標題「我通過自定義視圖來提供文件」。 –

+0

我的推理是,它是由Django自動完成的,只需要一些配置線,我認爲可以使用某種類似中間件的設置來實現這一點。但是,如果你們都說這是最好的選擇,那麼我會去做。我應該從頭開始編寫這個視圖還是以某種方式修改Django使用的解決方案,您的建議是什麼? – mateuszb

回答

0

我想你要找的是X-SENDFILE爲Apache或X阿塞爾 - 重定向Nginx的。 Django會接受所有對靜態文件的請求,並將其內部重定向到一個請求的文件,以便用戶不能看到真實的路徑和文件名。在應用服務器成功驗證後,通過Web服務器發送受保護文件是一種常見的解決方案。

如Nginx的一個例子您設置一個內部的別名和文件的真實位置:

location ^~ /protected_files/ { 
    internal; 
    alias /real/location/protected_files/; 
} 

,並在Django查看你與內部重定向和有關文件的其他信息的響應:

file_path = 'real/path/to/the/file' # you should have your way to get it from url 
filename = 'filename-used-to-save-the-file' 
response = HttpResponse() 
content_type, encoding = mimetypes.MimeTypes().guess_type(full_path) 
response['Content-Type'] = content_type 
response['Content-Disposition'] = 'attachment; filename="%s"' % filename 
response['X-Accel-Redirect'] = '/protected_files/%s' % file_path 

的網址,你提供給用戶可你把一切在你的urls.py在兩者路由到視圖

你可以閱讀更多的X-更快遷移在重定向: https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/

+0

如果最後一行不是'response ['X-Accel-Redirect'] ='/ protected_files /%s'%filename'? – jojo

+0

@jojo:不,在我的例子中,file_path是具有真實文件名的文件的完整路徑。示例中的filename變量是用戶在下載文件時獲得的名稱(試圖在本地保存)。 –