Django + uWSGI + nginx url mapping

橙三吉。 提交于 2019-12-08 18:01:18

问题


I want to run Django with uWSGI behind a NGINX.

I will use Django as a API service which should live on this link: project.test/api The Django project itself is blank (1.9.6), just created a app, migrated and created a superuser.

My Project structure looks like this:
/vagrant/api/here-lives-whole-django
/vagrant/api/uwsgi_params
/vagrant/frontend/some-frontend-work-seperated-from-django

My NGINX setup looks like this:

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;
    }
}

The uwsgi_params file:

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;

My Django url pattern:

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

Atm. Im running Django with following command:
uwsgi --socket :8000 --wsgi-file wsgi.py

Im able to reach Django but when I try to access
www.testing.test/api/admin
I get a 404 (debug from 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.

I know it will be something very simple for people who are used to this stuff, forgive me because Im new.

Ps. I found some similar questions where people worked with

uwsgi_param SCRIPT_NAME /api;
uwsgi_modifier1 30; 

But this just made my Django tell me a 404 with

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

when I requested

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

回答1:


I had trouble to understand your question but basically it resumes to this: I want nginx to pass all calls to /api/ to django but django is receiving the URL with /api/ prefixed.


nginx trick (does not work for internal URLs)

I'd use nginx's rewrite to solve this

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

It shall drop the /api/ part of the URL and remain in the block to uwsgi_pass into Django.


django solution (dirty in my opinion)

The above works for the first URL going into django. Yet, django is clueless about the prefix that was removed and will have trouble to generate URLs to itself. That might not be a problem in some simple APIs but it would be a problem more often than not.

I guess, the only viable way is to add the prefix to the base URLconf.

from django.conf.urls import include

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

urlpatterns = [
    url(r'^api/', include(mypatterns)),
]

Although, I feel this is a very dirty solution.



来源:https://stackoverflow.com/questions/37402852/django-uwsgi-nginx-url-mapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!