【问题标题】:Django + uWSGI + nginx url mappingDjango + uWSGI + nginx url 映射
【发布时间】:2016-09-21 00:49:13
【问题描述】:

我想在 NGINX 后面使用 uWSGI 运行 Django。

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

我的项目结构如下所示:
/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;
    }
}

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;

我的 Django 网址模式:

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

自动取款机。我使用以下命令运行 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.

我知道对于习惯了这些东西的人来说这将是一件非常简单的事情,请原谅我,因为我是新手。

附言。我在人们合作过的地方发现了一些类似的问题

uwsgi_param SCRIPT_NAME /api;
uwsgi_modifier1 30; 

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

Request URL:    http://www.testing.test/api/api/admin

当我请求时

Request URL:    http://www.testing.test/api/admin

【问题讨论】:

    标签: django url nginx uwsgi


    【解决方案1】:

    我很难理解你的问题,但基本上它恢复到这个:我希望 nginx 将所有对 /api/ 的调用传递给 django,但 django 正在接收带有 /api/ 前缀的 URL。


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

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

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

    它将删除 URL 的 /api/ 部分并保留在 Django 中 uwsgi_pass 的块中。


    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)),
    ]
    

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

    【讨论】:

    • 我尝试在链接 domain.test/api/* 上运行 Django,所以应该可以像这样 domain.test/api/admin 访问 Djangos build in admin。如果我按照您描述的方式更改我的项目并尝试转到 domain.test/api/admin 我将被扔到 domain.test/admin 。
    • 你不会因为break而被抛出,它确保rewrite不会被抛出回URL匹配。然而,django 为自身生成 URL 存在问题(我更新了答案以反映这一点)。我想,为基本 URLconf 中的所有 URL 提供 /api/ 前缀是肮脏但有效的解决方案
    • 确实或看起来确实如此。当我输入 domain.test/api/admin 它更改为 domain.test/admin 。顺便提一句。我相信我把一些东西搞砸了,因为我没有遵循你的旧答案,因为你删除了它们。你还记得你写了什么吗?可以帮我恢复虚拟机上的一些配置。
    • 我在喋喋不休地谈论随机 uWSGI 配置,因为我误读了你的问题。这完全是我的错。然而,对于 uwsgi 配置的一个很好的例子,我总是对this guy's gist post
    • 在设置 rewrite ^/api/(.*) /$1 break; 之后,我还必须有 uwsgi_param SCRIPT_NAME /api; 才能让 Django 正确路由。我整天都被这件事难住了,这真的很有帮助!
    猜你喜欢
    • 2014-05-31
    • 2011-10-10
    • 2011-11-25
    • 2017-04-12
    • 2015-11-08
    • 2014-08-09
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多