2010-04-22 45 views
15

所以我當然知道,通過Django提供靜態文件會直接發送給你,但我很困惑如何使用自定義url來掩蓋使用Django的文件的真實位置。 Django: Serving a Download in a Generic View但我接受的答案似乎是做錯事情的「錯誤」方式。Django:服務媒體在自定義URL後面

urls.py:

url(r'^song/(?P<song_id>\d+)/download/$', song_download, name='song_download'), 

views.py:

def song_download(request, song_id): 
    song = Song.objects.get(id=song_id) 
    fsock = open(os.path.join(song.path, song.filename)) 

    response = HttpResponse(fsock, mimetype='audio/mpeg') 
    response['Content-Disposition'] = "attachment; filename=%s - %s.mp3" % (song.artist, song.title) 

    return response 

此解決方案完美但不是完全足夠的事實證明。如何避免在通過nginx/apache提供服務時直接鏈接到mp3? -

編輯1附加信息

目前我可以用這樣的地址讓我的文件: http://www.example.com/music/song/1692/download/ 但上述方法是魔鬼的工作。

如何才能完成上面得到的東西,同時仍然使nginx/apache服務於媒體?這是應該在網絡服務器級完成的嗎?一些瘋狂的mod_rewrite?

http://static.example.com/music/Aphex%20Twin%20-%20Richard%20D.%20James%20(V0)/10%20Logon-Rock%20Witch.mp3

EDIT 2 - 附加其他信息

我使用nginx的我的前端和反向代理服務器後面的Apache /開發服務器,所以我想,如果它確實需要某種形式的mod_rewrite的工作中,我將有找到可以與nginx一起工作的東西。

回答

15

爲了擴大以前的答案,你應該能夠修改下面的代碼,讓nginx直接提供你的下載文件,同時仍然保護文件。

首先添加一個位置,如:

location /files/ { 
    alias /true/path/to/mp3/files/; 
    internal; 
} 

您nginx.conf文件(內部使得這種不能直接訪問)。然後你需要一個Django View如下所示:

def song_download(request, song_id): 
    try: 
     song = Song.objects.get(id=song_id) 
     response = HttpResponse() 
     response['Content-Type'] = 'application/mp3' 
     response['X-Accel-Redirect'] = '/files/' + song.filename 
     response['Content-Disposition'] = 'attachment;filename=' + song.filename 
    except Exception: 
     raise Http404 
    return response 

這將把文件下載到nginx。

+0

這幾乎是我所需要的,謝謝! – TheLizardKing 2010-04-23 12:09:42

+0

謝謝你們倆。我一直在尋找解決方案,並且獲得了很多噪音! – Sebastien 2017-01-05 03:10:23

1

httpdNginx都可以通過標題指定一個靜態文件來提供服務。雖然確切的標題不盡相同,但最好在設置中添加一些內容以選擇方法。

3

其基本思想是讓您的Django視圖重定向到您的媒體服務器提供的安全URL。

請參閱mod_wsgi作者Graham Dumpleton的建議this list