部署Django/DRF纯API项目后无法访问static和media资源的配置问题
首先明确:纯DRF API项目如果需要对外提供static或media资源(比如上传的文件、admin后台静态文件),必须用Nginx这类web服务器来托管静态资源——Django自带的开发服务器(runserver)可以处理静态文件,但生产环境下性能极差且不安全,官方也不推荐直接用Django处理生产环境的静态文件请求。
一、先确认Django静态资源收集是否完成
你的settings配置里已经指定了STATIC_ROOT和MEDIA_ROOT,但需要先执行静态资源收集命令,把所有静态文件(包括DRF、admin的默认静态文件)归集到STATIC_ROOT目录:
python manage.py collectstatic
执行时会提示确认,输入yes即可。这一步很关键,否则STATIC_ROOT目录里会没有文件,Nginx自然找不到。
二、调整Nginx虚拟主机配置
你当前的问题核心是location /的配置错误——它指向了包含index.html的目录,但你的API项目没有这个文件,而且这个配置会拦截所有请求(包括/static/和/media/),导致后面的静态资源location规则失效。
正确的Nginx配置示例(替换你现有的配置)
假设你的Django项目通过uWSGI或Gunicorn运行在127.0.0.1:8000,项目的绝对路径是/var/www/your_drf_project(请替换成你实际的路径):
server { listen 80; # 或者你需要的端口,比如8000 server_name 101.20.32.76; # 你的服务器IP或域名 # 托管media资源:匹配所有/media/开头的请求 location /media/ { alias /var/www/your_drf_project/media/; # 替换为你的MEDIA_ROOT绝对路径 expires 30d; # 缓存优化,可选 } # 托管static资源:匹配所有/static/开头的请求 location /static/ { alias /var/www/your_drf_project/static/; # 替换为你的STATIC_ROOT绝对路径 expires 30d; # 缓存优化,可选 } # 把所有其他请求反向代理到Django应用服务 location / { proxy_pass http://127.0.0.1:8000; # 替换为你的uWSGI/Gunicorn监听地址 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-Proto $scheme; } }
配置要点说明:
- location顺序:Nginx会优先匹配更精确的location规则(比如
/media/、/static/),所以要把这两个规则放在location /前面,避免被反向代理规则拦截。 - 路径正确性:
alias后面的路径必须是服务器上MEDIA_ROOT和STATIC_ROOT的绝对路径,注意路径末尾的/不能少,否则会导致路径拼接错误。 - 反向代理配置:
location /不再指向静态目录,而是把所有非静态资源的请求转发给Django的应用服务(uWSGI/Gunicorn),这样API接口就能正常访问了。
三、权限检查
确保Nginx的运行用户(通常是nginx用户)对static和media目录有读权限,否则会返回403错误:
# 给目录设置正确的权限 chown -R nginx:nginx /var/www/your_drf_project/static/ /var/www/your_drf_project/media/ chmod -R 755 /var/www/your_drf_project/static/ /var/www/your_drf_project/media/
四、验证配置并重启Nginx
修改配置后,先检查Nginx配置是否合法:
nginx -t
如果提示test is successful,就重启Nginx生效:
systemctl restart nginx
现在你再访问http://101.20.32.76/media/(或对应的端口),应该就能正常访问静态资源了;同时API接口也能通过Nginx反向代理正常请求。
内容的提问来源于stack exchange,提问作者qg_java_17137

