我希望网站上的用户能够下载路径被遮蔽的文件,这样他们就不能直接下载。
例如,我希望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和视图来显示它?
当前回答
Django建议您使用另一台服务器来提供静态媒体(在同一台机器上运行另一台服务器是可以的)。他们建议使用lighttp这样的服务器。
设置起来非常简单。然而。如果'somefile.txt'是在请求时生成的(内容是动态的),那么你可能想让django来服务它。
Django Docs -静态文件
其他回答
使用https://github.com/johnsensible/django-sendfile: https://gist.github.com/iutinvg/9907731提供对静态html文件夹的受保护访问
S.Lott有“好的”/简单的解决方案,elo80ka有“最好的”/高效的解决方案。这是一个“更好”/中间的解决方案-没有服务器设置,但更有效的大文件比天真的修复:
http://djangosnippets.org/snippets/365/
基本上,Django仍然处理文件的服务,但不会一次将整个文件加载到内存中。这允许您的服务器(缓慢地)在不增加内存使用的情况下提供大文件。
同样,S.Lott的X-SendFile对于较大的文件仍然更好。但如果你不能或不想为此费心,那么这个中间解决方案将为你带来更好的效率,而不会带来麻烦。
另一个项目可以看看:http://readthedocs.org/docs/django-private-files/en/latest/usage.html 看起来很有希望,但还没有亲自测试过。
基本上,该项目抽象了mod_xsendfile配置,并允许你做以下事情:
from django.db import models
from django.contrib.auth.models import User
from private_files import PrivateFileField
def is_owner(request, instance):
return (not request.user.is_anonymous()) and request.user.is_authenticated and
instance.owner.pk = request.user.pk
class FileSubmission(models.Model):
description = models.CharField("description", max_length = 200)
owner = models.ForeignKey(User)
uploaded_file = PrivateFileField("file", upload_to = 'uploads', condition = is_owner)
对于一个非常简单但不是有效或可扩展的解决方案,你可以使用内置的django serve视图。这对于快速原型或一次性工作是非常好的,但正如在这个问题中所提到的,你应该在生产中使用apache或nginx之类的东西。
from django.views.static import serve
filepath = '/some/path/to/local/file.txt'
return serve(request, os.path.basename(filepath), os.path.dirname(filepath))
“下载”只是一个HTTP报头更改。
请参阅http://docs.djangoproject.com/en/dev/ref/request-response/#telling-the-browser-to-treat-the-response-as-a-file-attachment了解如何回复下载。
“/download”只需要一个URL定义。
请求的GET或POST字典将有“f=somefile.txt”信息。
您的视图函数将简单地合并基本路径与“f”值,打开文件,创建并返回一个响应对象。它应该少于12行代码。