我有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
Serving multiple Django applications with Nginx and Gunicorn
我放弃了,只是为此项目创建了单独的子域。
答案 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_URL
:STATIC_URL = '/api/static'
...但这是一个肮脏的技巧,我同意。正确的方法是将其固定在Django端。
另请参阅https://stackoverflow.com/a/57009760/1657819,可能有点相关