I've been trying to make this work on my own for months now, but I just couldn't figure out what is wrong with my code, I'm running django + gunicorn + nginx, nginx it's set as a reverse proxy to gunicorn and I want download files using nginx which is the best way instead of leaving all the work to django backend which is slow. Anyway here is my sites-available config:
server {
listen 8080;
server_name 127.0.0.1;
client_max_body_size 10M;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/myuser/Dev/myproject/src;
}
location / {
proxy_set_header Host $http_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-Proto $scheme;
proxy_pass http://unix:/home/myuser/Dev/myproject/src/myproject.sock;
}
location /attachments/ {
internal;
alias /home/myuser/Dev/myproject/src/media/files;
}
}
I tried adding ~^ and ^~ to the location block, changing the name, using absolute paths, nothing worked
my urls.py (here the important url is 'attachment/download/int:id'):
from django.urls import path
from .views import (
issue_detail_view,
issue_update_view,
issue_list_view,
issue_upload_attachment,
issue_download_attachment,
issue_delete_attachment
)
app_name = 'issues'
urlpatterns = [
path('<int:id>', issue_detail_view, name='issues_detail'),
path('<int:id>/update', issue_update_view, name='issues_update'),
path('<int:id>/list', issue_list_view, name='issues_list'),
path('<int:id>/attachment', issue_upload_attachment, name='issues_upload_attachment'),
path('<int:id>/attachment/delete', issue_delete_attachment, name='issues_delete_attachment'),
path('attachment/download/<int:id>', issue_download_attachment, name='issues_download_attachment')
]
and my views.py:
def issue_download_attachment(request, *args, **kwargs):
id_ = kwargs.get('id')
attachment = Attachment.objects.get(id=id_)
filename = attachment.file.name.split('/')[2] #this line gets the filename only ('example.jpg')
response = HttpResponse()
# Let NGINX handle it
#it's inefficient to let django backend handle file downloads
#response.content = attachment.file.read()
response["Content-Disposition"] = "attachment; filename={0}".format(filename)
#I could'n make this next line work to serve files using nginx
response["X-Accel-Redirect"] = "/attachments/{0}".format(filename)
return response
files are stored at /home/myuser/Dev/myproject/src/media/files and the uploaded files seem to be owned by the root user and group and other just have read-only permissions (at this point I don't even know if this is important). When I try to download the file, it just shows at my downloads tab the id of the attachment and "interrupted: No file"
I've been following this tutorial on serving files with django and many many others perfectly but I can't get it to work (even all the previous answers here on stackoverflow didn't help me so I'm just thinking this might be an environment error idk)