提问者:小点点

Django-在子路径中运行时静态文件出现问题


我在子路径示例中运行了django应用程序。com/api/。大部分是RESTAPI(我使用django rest框架),所有请求都正常工作。但静态文件到处都有错误的路径——在管理面板和请求页面中(在django rest框架中,您有前端来调查事情)。Django不知怎的认为,所有静态文件都在示例中。com/back/static/,当它们位于示例中时。com/api/back/static/

还有示例。com/api/admin重定向到示例。com/admin/login/,但在手动转到示例之后。com/api/admin/login/一切都很顺利(但仍然没有样式)。

我的堆栈是nginx Django 2.0.5在docker容器中运行。

nginx配置:

location /api/ {
    proxy_pass            http://localhost:8000/;
    proxy_read_timeout    90;
    proxy_connect_timeout 90;
    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      Proxy "";
}

当涉及到Django时,STATIC\u URL被设置为os。路径join(BASE_DIR,“static/”FORCE_SCRIPT_NAME未设置,但设置后,它根本不起作用。

有什么想法吗?

[更新]

经过几个小时的战斗,我放弃了。这个问题与uwsgi没有意识到它在子路径中运行有关。这里有一些链接,可以对有类似问题的人有用:

在子路径中通过nginx uwsgi运行django应用程序

在子路径上运行Django

使用Nginx和GUnicorn为多个Django应用程序提供服务

Django WSGI路由

我放弃了,只是为这个项目创建了单独的子域。


共3个答案

匿名用户

如果您proxy\u-passNginx中的一个位置,并将URI添加到proxy\u-pass指令中,则您告诉Nginx从原始请求URL中删除该URI,并将该部分请求URI替换为proxy\u-passURI。因此:

location /api/ {
    proxy_pass            http://localhost:8000/;

告诉Nginx一个对示例的请求。com/api/path/to/whatever/应该被代理http://localhost:8000/path/to/whatever/

如果您想将原始未更改的请求URI传递给代理,请从proxy_pass指令的末尾删除/

匿名用户

这是Django的一个已知问题。

预期行为

外部世界(nginx\uwsgi\whatever)应该有SCRIPT\u NAME头(在您的情况下,它将等于/api),并将其转发给Django。

Django应该尊重这个头,并为用{%url...%}标记生成的URL添加它(它已经这样做了),并为用{%静态...%}生成的静态文件链接添加它(它不起作用,请参见提到的问题)。

为了解决这个问题,您可以直接将前缀附加到STATIC_URLSTATIC_URL='/api/静态'...但这是一个肮脏的黑客,我同意。正确的方法是将它固定在Django端。

也看到https://stackoverflow.com/a/57009760/1657819,可能有点相关

匿名用户

将此代码添加到nginx配置中:

location /static/ {
    alias /path/static/;
}

为了读取静态文件,您应该定义静态文件的位置。