配置Nginx时Django自定义404页面无法渲染的解决咨询
这个问题我之前部署Django项目时也碰到过,核心原因是Nginx在检测到请求的路径不存在时,直接返回了自己的默认404页面,根本没把请求传给Django处理。咱们一步步来搞定它:
解决方案步骤
1. 调整Nginx配置,让所有非静态请求都交给Django处理
你没贴完整的Nginx配置,这恰恰是问题的关键。你需要确保Nginx只接管静态文件、媒体文件的请求,所有其他不管存在与否的路径,都转发给Django的WSGI服务。给你一个标准的配置示例,你可以对应修改:
server { listen 80; server_name your_domain.com; # 换成你的域名或IP # 处理静态文件请求,路径要和Django的STATIC_ROOT对应 location /static/ { root /path/to/your/myblog_project; # 项目根目录 expires 30d; # 静态文件缓存优化,可选 } # 如果有媒体文件,加上这个块,路径对应MEDIA_ROOT location /media/ { root /path/to/your/myblog_project; } # 核心配置:所有其他请求转发给Django location / { # 如果你用uwsgi,就用下面两行 include uwsgi_params; uwsgi_pass unix:/path/to/your/uwsgi.sock; # 换成你的uwsgi sock路径或端口 # 如果你用gunicorn,就替换成proxy_pass # proxy_pass http://127.0.0.1:8000; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # 重中之重:禁止Nginx拦截Django返回的404错误 uwsgi_intercept_errors off; # uwsgi用这个 # proxy_intercept_errors off; # gunicorn用这个 } }
这里的关键是uwsgi_intercept_errors off或者proxy_intercept_errors off——默认Nginx会拦截后端返回的4xx/5xx错误,替换成自己的页面,关掉这个参数,就能让Django的自定义404页面正常返回了。
2. 确认Django端的404配置没问题
你已经做了基础配置,但再快速核对一遍:
- 确保
myblog/urls.py里的handler404 = 'views.handler404'路径正确,比如如果你的视图在myblog/views.py,那这个写法没问题;如果是其他app的视图,要写成app_name.views.handler404。 - 你的
handler404视图函数必须返回带status=404的响应,你写的return render(requests, '404.html', status=404)完全正确,这能让浏览器识别出这是404状态码,同时渲染自定义页面。 - 检查
templates/404.html是否存在,继承的base.html有没有语法错误,避免模板渲染失败导致Django返回默认404。
3. 重启服务生效
修改完Nginx配置后,一定要重启Nginx让配置生效:
sudo systemctl restart nginx
如果用了uwsgi或gunicorn,也建议重启一下对应的服务,确保所有配置都同步:
# uwsgi示例 sudo systemctl restart uwsgi # gunicorn示例 sudo systemctl restart gunicorn
排查小技巧
如果还是没效果,可以试试:
- 直接访问Django的WSGI服务(比如
http://127.0.0.1:8000/随便输一个不存在的路径),看看Django本身能不能返回自定义404页面,先排除Django端的问题。 - 查看Nginx的错误日志(一般在
/var/log/nginx/error.log),看看有没有请求转发失败的报错,比如路径不对、权限问题之类的。
内容的提问来源于stack exchange,提问作者Carlpeng
相关产品推荐
相关产品推荐

