如何在Django与Nginx中统一设置URL前缀并支持灵活修改
针对你要给Django项目加全局可修改的URL前缀,同时配合Nginx反向代理到指定路径的需求,这里有一套简洁的实现方案,确保你能在单一位置修改前缀,同时满足代理访问的要求:
一、Django端:配置全局可修改的URL前缀
我们可以利用Django的FORCE_SCRIPT_NAME设置来实现全局URL前缀,而且只需要改一处就能更新所有URL(包括模板里生成的链接):
修改settings.py,添加全局前缀变量
在你的项目settings.py文件中加入以下配置:# settings.py # 这里设置你想要的基础前缀,以后改前缀只需要改这一行 FORCE_SCRIPT_NAME = '/myproject' # 同步调整静态文件和媒体文件的URL,确保它们也带上前缀 STATIC_URL = f"{FORCE_SCRIPT_NAME}/static/" MEDIA_URL = f"{FORCE_SCRIPT_NAME}/media/"保持urls.py不变
你的原有urls.py不需要做任何修改,Django会自动把FORCE_SCRIPT_NAME作为所有URL的前缀:urlpatterns = [ url(r'^$', index, name='index'), url(r'^admin/', admin.site.urls), url(r'^myapp/', include('myapp.urls')) ]这样配置后,访问
http://127.0.0.1:8000/myproject/会对应原来的根视图,http://127.0.0.1:8000/myproject/admin/对应后台,而且模板里用{% url 'index' %}生成的链接会自动带上/myproject前缀,完全不用手动修改模板里的路径。以后想改成/project2,只需要改settings.py里的FORCE_SCRIPT_NAME就行。
二、Nginx端:配置反向代理到指定路径
接下来调整Nginx的配置,让它把/myname/开头的请求转发到Django的前缀路径上:
修改你的Nginx server配置如下:
server { location /myname/ { # 这里的proxy_pass要对应Django的FORCE_SCRIPT_NAME前缀,末尾斜杠不能少 proxy_pass http://127.0.0.1:8000/myproject/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; # 添加这两个头让Django正确识别客户端信息 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } }
配置说明:
location /myname/表示Nginx会拦截所有以/myname/开头的请求;proxy_pass后面的http://127.0.0.1:8000/myproject/会把请求转发到Django服务的/myproject/路径下;- 末尾的斜杠很重要,它会让Nginx把
/myname/xxx转换成/myproject/xxx转发给Django。
这样配置后,你访问http://yourdomain/myname/myproject/(如果Nginx监听80端口)或者http://127.0.0.1:8000/myname/myproject/(如果Nginx监听8000端口)就能正常访问你的项目,所有子路径比如/myname/myproject/admin也能正确对应到Django的后台。
最后要注意的点:
- 修改配置后,记得重启Django服务和Nginx服务才能生效;
- 如果是生产环境,建议让Nginx直接托管静态文件和媒体文件,避免Django处理这些请求,可以在Nginx里单独添加
location配置指向静态文件目录; - 如果以后要修改Django的前缀,只需要更新settings.py里的
FORCE_SCRIPT_NAME,同时把Nginx的proxy_pass里的路径对应修改即可(如果需要同步调整代理路径的话)。
内容的提问来源于stack exchange,提问作者Manjunath J

