所以我想从/home/username/music
的文件夹中提供几个mp3。我不认为这会是一个大问题,但我对如何使用通用视图和我自己的网址有点困惑。
urls.py
url(r'^song/(?P<song_id>\d+)/download/$', song_download, name='song_download'),
我正在关注的示例可以在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
我实际上不知道如何传达我希望它吐出我的mp3而不是它现在做的是输出.mp3与所有当前页面html包含。我的模板应该是我的mp3吗?我是否需要设置apache来提供文件,或者Django是否能够从文件系统中检索mp3(当然是适当的权限)并提供服务?如果确实需要配置Apache,我该如何告诉Django?
提前致谢。这些文件都在HD上,所以我不需要在现场“生成”任何东西,我想尽可能防止泄露这些文件的位置。一个简单/歌曲/ 1234 /下载将是太棒了。
答案 0 :(得分:15)
为什么要使用通用视图执行此操作?没有通用视图,这很容易做到:
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
我不确定是否可以通过一般视图以某种方式使这项工作成为可能。但不管怎样,使用一个在这里是多余的。没有要渲染的模板,通用视图自动提供的上下文是无用的。
答案 1 :(得分:7)
将我对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
XSendFileOn on
和(取决于版本)XSendFileAllowAbove on
或XSendFilePath the/path/to/serve/from
。 这样您就不会透露文件位置,并将所有网址管理保留在django中。
答案 2 :(得分:1)
使用Django提供静态文件是一个坏主意,使用Apache,nginx等。
https://docs.djangoproject.com/en/dev/howto/static-files/deployment/