use*_*550 0 python django nginx python-3.x nginx-location
我希望Django仅为登录用户提供一些媒体文件(例如,用户上传的文件)。由于我的网站流量很少,我想我会保持简单,不要django-sendfile告诉Nginx什么时候提供文件。相反,我将让Django / Gunicorn完成这项工作。在我看来,这似乎要简单得多,对于人流量少的网站,这可能更安全。
但是,组织文件存储位置的最佳方法是什么?媒体文件都存储在下面MEDIA_ROOT,该目录由Nginx在生产中提供。如果我将文件上传到,MEDIA_ROOT/protected/我必须告诉Nginx不要在子目录中提供文件protected。
但这是个好主意吗?对我来说,首先允许Nginx访问/media/然后保护子目录似乎有点冒险/media/protected/。不使用的子目录MEDIA_ROOT存储受保护的文件会更好吗?
但是,如果我在模型中尝试类似以下操作:
upload_to='../protected/documents/%Y/%m/'
Run Code Online (Sandbox Code Playgroud)
Django抱怨:
SuspiciousFileOperation at /admin/core/document/add/
The joined path (/home/me/projects/project/protected/documents/2016/09/test.file) is located outside of the base path component (/home/me/projects/project/media)
Run Code Online (Sandbox Code Playgroud)
因此,我认为“离开”这不是一个好习惯MEDIA_ROOT。
存储和提供受保护的媒体文件的最佳解决方案是什么?
Ren*_*han 10
直接从视图中提供媒体文件(可能是大文件)并不好。您可以使用sendfilenginx 服务器中可用的扩展;一个示例 nginx 配置如下所示。
location /projects/project/media/{
# this path is not public
internal;
# absolute path
alias /projects/project/media/;
}
Run Code Online (Sandbox Code Playgroud)
改变你的看法
@login_required
def serve_protected_document(request, file):
document = get_object_or_404(ProtectedDocument, file="protected/documents/" + file)
# Split the elements of the path
path, file_name = os.path.split(file)
response = HttpResponse()
response["Content-Disposition"] = "attachment; filename=" + file_name
# nginx uses this path to serve the file
response["X-Accel-Redirect"] = document.name # path to file
return response
Run Code Online (Sandbox Code Playgroud)
链接:有关在 nginx 上配置 sendfile 扩展的更多详细信息在这里
我现在想出了以下解决方案:
我在Django设置中有此设置:
MEDIA_ROOT = "/projects/project/media/"
MEDIA_URL = "/media/
Run Code Online (Sandbox Code Playgroud)
在我的模型中,我要么:
document = models.FileField(upload_to="public/documents")
Run Code Online (Sandbox Code Playgroud)
要么
document = models.FileField(upload_to="protected/documents")
Run Code Online (Sandbox Code Playgroud)
这样,我现在在媒体文件目录中有两个子目录“ public”和“ protected”。
Nginx或Django的开发服务器仅提供“ public”子目录中的文件。
对于Django开发服务器:
if os.environ["ENVIRONMENT_TYPE"] == 'development':
urlpatterns += static(settings.MEDIA_URL + "public/", document_root=settings.MEDIA_ROOT + "public/")
Run Code Online (Sandbox Code Playgroud)
对于Nginx(用于生产):
location /media/public/ {
alias /projects/project/media/public/;
}
Run Code Online (Sandbox Code Playgroud)
当我要提供受保护的文档时,请执行以下操作:
在urls.py中:
url(r'^media/protected/documents/(?P<file>.*)$', core.views.serve_protected_document, name='serve_protected_document'),
Run Code Online (Sandbox Code Playgroud)
在views.py中:
@login_required()
def serve_protected_document(request, file):
document = get_object_or_404(ProtectedDocument, file="protected/documents/" + file)
# Split the elements of the path
path, file_name = os.path.split(file)
response = FileResponse(document.file,)
response["Content-Disposition"] = "attachment; filename=" + file_name
return response
Run Code Online (Sandbox Code Playgroud)
我将不胜感激!有更好的方法来实现这一点吗?
| 归档时间: |
|
| 查看次数: |
4410 次 |
| 最近记录: |