首页 > 解决方案 > 使用 Django 和 Nginx 上传和下载文件

问题描述

我目前正在尝试使用 Django 上传一些文件,它似乎大部分都在工作。我至少能够看到该文件已添加到 Django 管理面板中的特定模型中,但我无法打开它。此外,每当我尝试获取文件的 URL 时,我都会被转发到 Django 错误页面,并显示一个很好的错误:[Errno 2] No such file or directory: 'media/some_file.csv'

这是我的文件模型:

class File(models.Model):
    challenge = models.ForeignKey(Challenge, on_delete=models.CASCADE, default="")
    file = models.FileField(default="", upload_to="media/")

    def __str__(self):
        return self.challenge.challenge_id

设置.py:

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'server', 'static'),
    os.path.join(BASE_DIR, '..', 'media'),
)

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = 'media/'

上传功能:

def uploadChallengeFile(request):
    latestChallenge = Challenge.objects.last()
    for file in request.FILES.items():
        file_model = File(challenge=latestChallenge, file=file[0])
        file_model.save()

    data = {"data": [True]}
    return JsonResponse(data, safe=False)

下载功能:

def downloadFile(request, challenge_id):
    challenge = Challenge.objects.filter(challenge_id=challenge_id)
    filename = File.objects.filter(challenge=challenge).values("file")[0]["file"]
    content = open(File.objects.get(challenge=challenge).file.url).read()

    response = HttpResponse(content, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s' % filename

    return response

urls.py:

url(r'^api/start/download/(?P<challenge_id>[\w.@+-]+)/$', views.backendServices.downloadFile, name="download")

似乎 Django 正在保存文件的实例,但实际上并未存储它。我是否需要配置nginx.conf以提供/media目录中的文件或执行其他操作?任何帮助将不胜感激。

谢谢

标签: pythondjangonginx

解决方案


通常,您必须配置 nginx 以代理传递请求到 media/ 和 static/ 到您的 django 实例:

以下假设可以通过 http://django:8000 访问您的 django 服务,但如果您不使用 docker(并且它没有命名为 django),则更有可能是 http://localhost:8000

    location /static {
        proxy_pass        http://django:8000;
        proxy_redirect    default;
        proxy_set_header  Host $host;
        proxy_set_header  X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Host $server_name;
    }

    location /media {
        proxy_pass        http://django:8000;
        proxy_redirect    default;
        proxy_set_header  Host $host;
        proxy_set_header  X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Host $server_name;
    }

另外,确保在调试模式(通常是本地开发)下运行时设置 URL 路由,以便 django 处理它们

if settings.DEBUG:
    from django.views.static import serve
    from django.conf.urls.static import static

    urlpatterns += [
        url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
    ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)


推荐阅读