如何用Django创建私人下载区?

13 投票
3 回答
8010 浏览
提问于 2025-04-15 15:17

我想在一个使用Django的网站上实现一个私人下载区域。用户必须登录并拥有相应的权限,才能下载一些静态文件。

你有什么建议可以帮助我实现这个功能吗?有什么小窍门吗?

谢谢!

更新:也许是因为我的英语不好,或者我对这个架构了解不够(所以我才在问),但我的问题是:如何确保静态文件(由普通的网络服务器提供,不需要Django)能够通过Django的认证来控制访问。

我会更仔细地阅读Django的文档,但我不记得有现成的解决方案来解决这个问题。

更新2:我的主机提供商只支持FastCgi。

3 个回答

1

关于如何在Django中启用身份验证,有很多教程。如果你需要帮助,可以从这里开始。

接下来的步骤是创建一个视图,用来列出你的文件。去做这个吧,这都是Django的基础知识。如果在这个步骤遇到问题,可以回去看看Django教程,你一定能搞明白的。

最后,再回到第一个链接(这里再给你一次:身份验证文档),仔细看看LOGIN_REQUIRED装饰器。用这个装饰器来保护你的视图。

这些都是Django的基础内容。如果你完成了这些并且有一个具体的问题,可以在这里提问。不过你在Stack Overflow上提了一个比较开放的问题,这样不太容易得到帮助。

3

XSendfile听起来是个不错的方法,但设置起来似乎有点复杂。我决定使用一个更简单的方式。

根据emeryc的回答和Django的代码片段 http://www.djangosnippets.org/snippets/365/,我写了以下代码,似乎能实现我想要的效果:

@login_required
def serve_file(request, filename):
    fullname = myapp.settings.PRIVATE_AREA+filename
    try:
        f = file(fullname, "rb")
    except Exception, e:
        return page_not_found(request, template_name='404.html')
    try:
        wrapper = FileWrapper(f)
        response = HttpResponse(wrapper, mimetype=mimetypes.guess_type(filename)[0])
        response['Content-Length'] = os.path.getsize(fullname)
        response['Content-Disposition'] = 'attachment; filename={0}'.format(filename)
        return response
    except Exception, e:
        return page_not_found(request, template_name='500.html')
11

我在网上找到了一个讨论串,地址是这里

里面提到的三件事情你可能会感兴趣。

首先是 mod_python 的方法
然后是 mod_wsgi 的方法

这两种方法似乎都不是特别好。

更好的选择是 X-Sendfile 这个头部,它虽然不是完全标准的,但至少在 apache 和 lighttpd 中可以正常工作。

这里获取的一些信息,我们得到了以下内容。

@login_required
def serve_file(request, context):
    if <check if they have access to the file>:
        filename = "/var/www/myfile.xyz" 
        response = HttpResponse(mimetype='application/force-download') 
        response['Content-Disposition']='attachment;filename="%s"'%filename
        response["X-Sendfile"] = filename
        response['Content-length'] = os.stat("debug.py").st_size
        return response
    return <error state>

这应该几乎正是你想要的。只要确保你在使用的环境中开启了 X-Sendfile 支持就可以了。

撰写回答