Django:在通用视图中提供下载

The*_*ing 9 python django file

所以我想从一个文件夹中提供几个mp3 /home/username/music.我不认为这会是一个大问题,但我对如何使用通用视图和我自己的URL感到有点困惑.

urls.py

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

我下面的例子在Django的单证的普通视图部分发现: http://docs.djangoproject.com/en/dev/topics/generic-views/(这是在底部一路)

我不是100%肯定如何根据我的需要量身定制.这是我的views.py

def song_download(request, song_id):
    song = Song.objects.get(id=song_id)

    response = object_detail(
        request,
        object_id = song_id,
        mimetype = "audio/mpeg",
    )
    response['Content-Disposition'= "attachment; filename=%s - %s.mp3" % (song.artist, song.title)

    return response
Run Code Online (Sandbox Code Playgroud)

我实际上不知道如何传达我希望它吐出我的mp3而不是它现在做的是输出.mp3与所有当前页面html包含.我的模板应该是我的mp3吗?我是否需要设置apache来提供文件,或者Django是否能够从文件系统中检索mp3(当然是适当的权限)并提供服务?如果确实需要配置Apache,我该如何告诉Django?

提前致谢.这些文件都在HD上,所以我不需要在现场"生成"任何东西,我想尽可能防止泄露这些文件的位置.一个简单/歌曲/ 1234 /下载将是太棒了.

Ben*_*mes 17

为什么要使用通用视图执行此操作?没有通用视图,这很容易做到:

from django.http import HttpResponse


def song_download(request, song_id):
    song = Song.objects.get(id=song_id)
    fsock = open('/path/to/file.mp3', 'r')
    response = HttpResponse(fsock, content_type='audio/mpeg')
    response['Content-Disposition'] = "attachment; filename=%s - %s.mp3" % \
                                     (song.artist, song.title)
    return response
Run Code Online (Sandbox Code Playgroud)

我不确定是否可以通过一般视图以某种方式使这项工作.但不管怎样,使用一个在这里是多余的.没有要呈现的模板,通用视图自动提供的上下文是无用的.


xub*_*tix 8

将我对Tomasz Zielinski的评论包装成一个真实的答案:

出于几个原因,让apache/nginx/etc执行发送文件的工作确实更好.大多数服务器都有这种用例的机制:Apache和lighttpd都有xsendfile,nginx有X-Accel-Redirect.

这个想法是你可以使用django的所有功能,如漂亮的URL,验证方法等,但让服务器完成提供文件的工作.您的django视图必须做的是返回带有特殊标头的响应.然后,服务器将使用实际文件替换响应.

apache示例:

def song_download(request):
    path = '/path/to/file.mp3'
    response = HttpResponse()
    response['X-Sendfile'] = smart_str(path)
    response['Content-Type'] = "audio/mpeg"
    response['Content-Length'] = os.stat(path).st_size
    return response
Run Code Online (Sandbox Code Playgroud)
  • 安装mode_xsendfile
  • 添加XSendFileOn on和(取决于版本)XSendFileAllowAbove onXSendFilePath the/path/to/serve/from您的Apache配置.

这样您就不会透露文件位置,并将所有URL管理保留在django中.