Django:在自定义 URL 后面提供媒体服务

Posted

技术标签:

【中文标题】Django:在自定义 URL 后面提供媒体服务【英文标题】:Django: Serving Media Behind Custom URL 【发布时间】:2011-02-10 21:23:09 【问题描述】:

所以我当然知道通过 Django 提供静态文件会让你直接下地狱,但我对如何使用自定义 url 来掩盖使用 Django 的文件的真实位置感到困惑。 Django: Serving a Download in a Generic View 但我接受的答案似乎是“错误”的做事方式。

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

这个解决方案完美地工作,但事实证明还不够完美。如何避免直接链接到 mp3,同时仍然通过 nginx/apache 提供服务?

编辑 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

编辑 2 - 附加附加信息

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

【问题讨论】:

【参考方案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。

【讨论】:

谢谢你们俩。我一直在寻找该解决方案并收到很多噪音!【参考方案2】:

基本想法是让您的 Django 视图重定向到由您的媒体服务器提供的安全 URL。

请参阅 mod_wsgi 的作者 Graham Dumpleton 的建议 this list。

【讨论】:

【参考方案3】:

httpd 和 Nginx 都可以指定静态文件以通过标题提供服务。确切的标题会有所不同,因此最好在设置中添加一些内容以选择方法。

【讨论】:

以上是关于Django:在自定义 URL 后面提供媒体服务的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义模板标签中传递 url 标签?

在自定义模板标签中解析 Django 自定义模板标签

Bootstrap navbar 在自定义宽度上折叠媒体查询

如何在自定义 URL 上运行 Laravel mix?

如何在自定义 django 表单中隐藏 django 标签?

在自定义命令中与 Django 通道进行数据绑定