如何在子路径中托管 Django 项目?

How to host a Django project in a subpath?

我正在用 Django REST framework which is served via Gunicorn and Nginx. The project "exampleproject" has to run at a subpath such as: https://100.100.100.100/exampleproject(示例 IP 地址)构建一个 API。我没有注册IP的域名

目前,起始页按预期呈现在 https://100.100.100.100/exampleproject. However a the resource path for "products" does not work. Instead of https://100.100.100.100/exampleproject/products the start page displays https://100.100.100.100/products - 这不起作用。

我在 /etc/nginx/sites-enabled/default 中为 exampleproject 配置子路径如下:

server {

    # ...

    location /exampleproject/ {
        proxy_pass        http://localhost:8007/;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  Host $host;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
    }

当我手动访问https://100.100.100.100/exampleproject/products时,Nginx在/var/log/nginx/access.log中记录如下:

"GET /products/ HTTP/1.1" 404 151 "-"

我发现 here 需要在 settings.py 中的 Django 配置中添加以下设置:

FORCE_SCRIPT_NAME = '/exampleproject'

这似乎重写了嵌套资源的所有路径。

只需从代理传递 URL 中删除尾部斜线,如下所示:

proxy_pass http://localhost:8007;

如果在没有URI的情况下指定proxy_pass,则请求URI以与处理原始请求时客户端发送的相同形式传递给服务器,然后保留/exampleproject/部分.

参见:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

然后您需要配置 Django 以理解 /exampleproject/ 下的 URL。

首先,您可以通过像这样更新 urls.py 文件来为所有 URL 添加子路径:

urlpatterns = [url(r'^exampleproject/', include(urlpatterns))]

而且,如果您提供静态和媒体服务,只需在设置中更新:

MEDIA_URL = '/exampleproject/media/'
STATIC_URL = '/exampleproject/static/'

当然你可以创建一个自定义设置来复制这个或者让应用程序在没有子路径的情况下工作,我相信这是一个比 FORCE_SCRIPT_NAME 更好的解决方案,因为在那种情况下我发现我们需要无论如何都要更新 Django URLs。