我希望网站上的用户能够下载路径被遮蔽的文件,这样他们就不能直接下载。
例如,我希望URL是这样的:http://example.com/download/?f=somefile.txt
在服务器上,我知道所有可下载的文件都位于/home/user/files/文件夹中。
有没有一种方法可以让Django为下载提供这个文件,而不是试图找到一个URL和视图来显示它?
我希望网站上的用户能够下载路径被遮蔽的文件,这样他们就不能直接下载。
例如,我希望URL是这样的:http://example.com/download/?f=somefile.txt
在服务器上,我知道所有可下载的文件都位于/home/user/files/文件夹中。
有没有一种方法可以让Django为下载提供这个文件,而不是试图找到一个URL和视图来显示它?
当前回答
上面提到过,mod_xsendfile方法不允许在文件名中使用非ascii字符。
出于这个原因,我有一个补丁mod_xsendfile,将允许任何文件被发送,只要名称是url编码,和额外的头:
X-SendFile-Encoding: url
也会被发送。
http://ben.timby.com/?p=149
其他回答
这里只提到Django 1.10中提供的FileResponse对象
编辑:在寻找一种简单的通过Django进行文件流处理的方法时,我遇到了自己的答案,所以这里有一个更完整的例子(给未来的我)。它假设FileField名称为imported_file
views.py
from django.views.generic.detail import DetailView
from django.http import FileResponse
class BaseFileDownloadView(DetailView):
def get(self, request, *args, **kwargs):
filename=self.kwargs.get('filename', None)
if filename is None:
raise ValueError("Found empty filename")
some_file = self.model.objects.get(imported_file=filename)
response = FileResponse(some_file.imported_file, content_type="text/csv")
# https://docs.djangoproject.com/en/1.11/howto/outputting-csv/#streaming-large-csv-files
response['Content-Disposition'] = 'attachment; filename="%s"'%filename
return response
class SomeFileDownloadView(BaseFileDownloadView):
model = SomeModel
urls . py
...
url(r'^somefile/(?P<filename>[-\w_\\-\\.]+)$', views.SomeFileDownloadView.as_view(), name='somefile-download'),
...
Django建议您使用另一台服务器来提供静态媒体(在同一台机器上运行另一台服务器是可以的)。他们建议使用lighttp这样的服务器。
设置起来非常简单。然而。如果'somefile.txt'是在请求时生成的(内容是动态的),那么你可能想让django来服务它。
Django Docs -静态文件
尝试@Rocketmonkeys解决方案,但下载的文件被存储为*.bin,并被随机命名。这当然不好。添加来自@elo80ka的另一行就解决了这个问题。 下面是我现在使用的代码:
from wsgiref.util import FileWrapper
from django.http import HttpResponse
filename = "/home/stackoverflow-addict/private-folder(not-porn)/image.jpg"
wrapper = FileWrapper(file(filename))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(filename)
response['Content-Length'] = os.path.getsize(filename)
return response
你现在可以把文件存储在一个私有目录中(不是在/media或/public_html中),并通过django将它们暴露给特定的用户或在特定的情况下。 希望能有所帮助。 感谢@elo80ka, @S。Lott和@Rocketmonkeys的答案,得到了完美的解决方案=)
试一试:https://pypi.python.org/pypi/django-sendfile/
“一旦Django检查了权限,抽象的卸载文件上传到web服务器(例如Apache的mod_xsendfile)。”
使用https://github.com/johnsensible/django-sendfile: https://gist.github.com/iutinvg/9907731提供对静态html文件夹的受保护访问