Django + uWSGI + nginx url映射

7 django url nginx uwsgi

我想在NGINX后面用uWSGI运行Django.

我将使用Django作为API服务,它应该存在于这个链接上:project.test/api Django项目本身是空白的(1.9.6),只是创建了一个应用程序,迁移并创建了一个超级用户.

我的项目结构如下所示:
/ vagrant/api/here-lives-whole-django
/ vagrant/api/uwsgi_params
/ vagrant/frontend/some-frontend-work-seperated-from-django

我的NGINX设置如下所示:

upstream testing {
    server 127.0.0.1:8000;
}

server {
    listen   80;

    server_name www.testing.test;

    charset  utf-8;

    client_max_body_size  75M;

    access_log  /var/log/nginx/www.testing.test.access.log;
    error_log  /var/log/nginx/www.testing.test.error.log;

    location /api/ {
        include /vagrant/api/uwsgi_params;
        uwsgi_pass testing;
    }

    location / {
        root /vagrant/frontend;
    }
}
Run Code Online (Sandbox Code Playgroud)

uwsgi_params文件:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
Run Code Online (Sandbox Code Playgroud)

我的Django网址模式:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]
Run Code Online (Sandbox Code Playgroud)

自动取款机.我用以下命令运行Django
:uwsgi --socket:8000 --wsgi-file wsgi.py

我能够访问Django,但当我尝试访问
www.testing.test/api/admin时,
我得到一个404(来自Django的调试).

Page not found (404)
Request Method: GET
Request URL:    http://www.testing.test/api/admin
Using the URLconf defined in testing.urls, Django tried these URL patterns, in this order:
^admin/
The current URL, api/admin, didn't match any of these.
Run Code Online (Sandbox Code Playgroud)

我知道对于习惯这种东西的人来说这将是非常简单的事情,请原谅我,因为我很新.

PS.我找到了一些与人合作的类似问题

uwsgi_param SCRIPT_NAME /api;
uwsgi_modifier1 30; 
Run Code Online (Sandbox Code Playgroud)

但这只是让我的Django告诉我404

Request URL:    http://www.testing.test/api/api/admin
Run Code Online (Sandbox Code Playgroud)

当我要求时

Request URL:    http://www.testing.test/api/admin
Run Code Online (Sandbox Code Playgroud)

gro*_*mal 6

我很难理解您的问题,但基本上它可以继续进行:我想nginx将所有呼叫传递/api/给django,但是django正在接收带有/api/前缀的URL 。


nginx技巧(不适用于内部URL)

我会用nginx重写来解决这个问题

location /api/ {
    rewrite ^/api/(.*) /$1  break;
    include /vagrant/api/uwsgi_params;
    uwsgi_pass testing;
}
Run Code Online (Sandbox Code Playgroud)

它将删除/api/URL 的一部分,并保留在uwsgi_passDjango中。


django解决方案(我认为很脏)

以上适用于进入django的第一个URL。但是,django对于已删除的前缀一无所知,并且很难生成指向其自身的URL。在某些简单的API中,这可能不是问题,但往往是一个问题。

我猜,唯一可行的方法是将前缀添加到基本URLconf中。

from django.conf.urls import include

mypatterns = [
    url(r'^admin/', admin.site.urls),
]

urlpatterns = [
    url(r'^api/', include(mypatterns)),
]
Run Code Online (Sandbox Code Playgroud)

虽然,我觉得这是一个非常肮脏的解决方案。

  • 设置`rewrite ^ / api /(.*)/ $ 1 break;`之后,我还必须有`uwsgi_param SCRIPT_NAME / api;`才能使Django正确路由。我整天都为此感到困惑,这真的很有帮助! (2认同)