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

时间:2018-07-04 09:27:02

标签: python django nginx

我有django应用程序在子路径example.com/api/中运行。大部分是rest API(我使用django-rest-framework),并且所有请求都正常工作。但是静态文件到处都有错误的路径-在管理面板和请求页面中(在django-rest-framework中,您有前端进行调查)。 Django以某种方式认为,当所有静态文件位于example.com/back/static/中时,它们都位于example.com/api/back/static/中。

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

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

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_URL设置为os.path.join(BASE_DIR, "static/")的情况下,FORCE_SCRIPT_NAME没有设置,但是设置后,它根本无法工作。

有什么想法吗?

[更新]

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

Run django app via nginx+uwsgi in a subpath

Running Django on a subpath

Serving multiple Django applications with Nginx and Gunicorn

Django WSGI routing

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

3 个答案:

答案 0 :(得分:1)

如果您在Nginx中proxy_pass中的某个位置并将URI添加到您的proxy_pass指令中,则是在告诉Nginx将其从原始请求URL中删除,然后用您的{{ 1}} URI。所以这个:

proxy_pass

告诉Nginx,对example.com/api/path/to/whatever/的请求应被代理到http://localhost:8000/path/to/whatever/

如果您希望将原始的未更改请求URI传递给代理,请从location /api/ { proxy_pass http://localhost:8000/; 指令的末尾删除/

答案 1 :(得分:0)

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

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

您应该定义静态文件的位置,以便读取它。

答案 2 :(得分:0)

这是Django中已知的issue

预期的行为

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

Django应该尊重该标头,并将其添加到使用{%url ... %}标记生成的URL(已经添加)以及使用{% static ... %}生成的静态文件链接中(无效,请参见所提到的问题)

要解决此问题,您可以将前缀直接附加到STATIC_URLSTATIC_URL = '/api/static' ...但这是一个肮脏的技巧,我同意。正确的方法是将其固定在Django端。

另请参阅https://stackoverflow.com/a/57009760/1657819,可能有点相关