一尘不染

Django:在自定义网址后投放媒体

django

此,我当然知道通过Django提供静态文件会直接将您送入地狱,但是我对如何使用自定义网址掩盖Django使用文件的真实位置感到困惑。 Django:在一般视图中提供下载服务,但我接受的答案似乎是“错误”的处理方式。

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服务媒体的同时,我如何才能实现上述目标?这是应该在Web服务器级别执行的操作吗?一些疯狂的mod_rewrite?

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

编辑2-其他信息

我将nginx用于前端和反向代理后备apache /开发服务器,因此,我认为如果确实需要某种mod_rewrite工作,我将不得不找到与nginx兼容的东西。


阅读 356

收藏
2020-04-01

共1个答案

一尘不染

为了扩展先前的答案,你应该能够修改以下代码,并让nginx直接提供你的下载文件,同时仍然保护文件。

首先添加一个位置,例如:

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

到你的nginx.conf文件(内部无法直接访问)。然后,你需要一个类似Django的视图:

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。

2020-04-01