Как мне отправить сгенерированный файл в Django через nginx в качестве загрузки?

#python #django #nginx

#python #django #nginx

Вопрос:

Я пытаюсь отправить сгенерированный zip-файл в мою папку мультимедиа через nginx, но я получил следующую ошибку: open() "/etc/nginx/htmltest.zip" failed (2: No such file or directory)

Каким-то образом nginx ищет файл в странно искаженном «/etc/nginx / html», я не понимаю, почему.

Я использую nginx через docker-compose, код работает просто отлично, если я не использую nginx и просто запускаю Django в режиме разработки.

 folder_path = os.path.join(settings.MEDIA_ROOT, str(uuid.uuid4()))
os.mkdir(folder_path)

shutil.make_archive(os.path.join(folder_path, "test"), 'zip', folder_path, "test")

response = download(os.path.join(folder_path, f"{zip_name}.zip"))


def download(path):
    if os.path.exists(path):

        with open(path, 'rb') as f:
            response = HttpResponse(f.read(), content_type="application/zip")
            response['Content-Disposition'] = 'inline;filename='   os.path.basename(path)
            response['X-Accel-Redirect'] = os.path.basename(path)
            return response

    raise Http404
 

Мой nginx.conf:

 upstream django_app {
    server web:8000;
}

server {

    listen 80;

    location / {
        proxy_pass http://django_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
        client_max_body_size 100M;
    }

    location /static/ {
        alias /code/static/;
    }

    location /media/ {
        alias /code/media/;
    }

}
 

MEDIA_ROOT в settings.py:

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

Ответ №1:

Вы неправильно используете nginx X-Accel-Redirect .

При использовании X-Accel-Redirect вам не нужно самостоятельно читать и отправлять файл из Django, nginx сделает это за вас. В этом весь смысл X-Accel-Redirect : разгрузка отправки файлов с сервера приложений на nginx (что в этом лучше).

Итак, удалите X-Accel-Redirect заголовок, тогда Django будет обслуживать файл напрямую.

Если вы хотите использовать X-Accel-Redirect , вам нужно настроить nginx, как описано в документации (ваша конфигурация не завершена, поскольку в ней отсутствует internal местоположение), а затем указать внутренний URL-адрес в X-Accel-Redirect заголовке (вы неправильно указываете путь к файловой системе).