在Django

时间:2017-03-04 18:56:01

标签: python django

现在,对于我的数据库中的每个Foo对象,我都有相关文件存储在具有以下结构some/example/path/foo/pk/name.txt的路径中。

在Django中提供服务的默认方式是在设置中指定MEDIA_ROOTMEDIA_URL。这样,我可以通过访问Foo object with id=1以及其他对象的类似方式来访问与localhost:8000/media/foo/1/name.txt相关的文件。

但我不希望向用户公开文件在内部的存储方式(目录结构,主键等),并从localhost:8000/media/mapped_path_to_name.txt提供服务。

目前,我能想到的唯一解决方案是创建负责提供文件的自定义视图,并在此视图中放置执行路径映射的逻辑。这个问题还有更优雅(简约)的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我认为您正在寻找的是Apache的X-Sendfile或Nginx的X-Accel-Redirect。 Django将获取静态文件的所有请求,并将其内部重定向到请求的文件,以便用户无法查看真实路径和文件名。在应用程序服务器成功进行身份验证后,通过Web服务器发送受保护文件是一种常见的解决方案。

作为Nginx中的一个示例,您可以设置内部别名和文件的真实位置:

location ^~ /protected_files/ {
   internal;
   alias /real/location/protected_files/;
}

并在Django视图中使用内部重定向和有关该文件的其他信息进行响应:

file_path = 'real/path/to/the/file' # you should have your way to get it from url
filename = 'filename-used-to-save-the-file'
response = HttpResponse()
content_type, encoding = mimetypes.MimeTypes().guess_type(full_path)
response['Content-Type'] = content_type
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
response['X-Accel-Redirect'] = '/protected_files/%s' % file_path

您为用户提供的网址可以是您在urls.py中添加的将其路由到视图的内容

您可以在以下位置阅读有关X-Accel-Redirect的更多信息: https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/