在子path中通过nginx + uwsgi运行django应用程序

我想在开发服务器的子目录别名中运行一个简单的testing项目。 基本的设置是一个nginx,其位置将子目录中的所有内容都传递给wsgi应用程序。

Django显然不知道它运行在一个子目录别名,这完全破坏了URL的生成和parsing。
我找不到在文档中的任何前缀类设置,我的谷歌福也没有那么多的帮助…所以我现在问这里。

我唯一find的是设置FORCE_SCRIPT_NAME至less修复了URL的生成。 (请参阅: http : //docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath )
可悲的是,这并不能解决urlconfparsing问题,即使提到的网站提示。

是否有可能在一个子目录别名运行Django的应用程序,如果是这样,如何?

nginxconfiguration:

server { location /fancyprojectname/static { alias /srv/fancyprojectname/static; } location /fancyprojectname/ { uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket; include uwsgi_params; } } 

编辑

所以,设置“uwsgi_param SCRIPT_NAME / fancyprojectname;” 在nginx的位置使FORCE_SCRIPT_NAME不必要 – 遗憾的是URL匹配仍然不起作用。

 from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Uncomment the admin/doc line below to enable admin documentation: # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls)), ) 

我认为发生了什么事情:由于pipe理正则expression式以“^ admin”开始,而实际的URL是“fancyprojectname / admin /”,即使设置了SCRIPT_NAME,Django也无法正确匹配URL。

解决scheme

所以,SCRIPT_NAME的确是一个问题。

WSGI规范说明如下:

SCRIPT_NAME请求URL的“path”的初始部分,对应于应用程序对象,以便应用程序知道它的虚拟“位置”。 如果应用程序对应于服务器的“根”,则这可能是一个空string。

PATH_INFO请求URL的“path”的其余部分,在应用程序中指定请求目标的虚拟“位置”。 如果请求URL以应用程序根目标为准,并且没有结尾的斜杠,则这可能是一个空string。

Nginx不会自动设置SCRIPT_NAME,所以在任何情况下都需要设置。 之后PATH_INFO是错误的,因为在默认的设置中,Nginx将它设置为$ document_uri,这将是完整的URL。

“uwsgi_modifier1 30;” 告诉Nginx设置UWSGI_MODIFIER_MANAGE_PATH_INFO,这又告诉UWSGI去掉PATH_INFO的SCRIPT_NAME。

这些设置的组合似乎工作,因为Django现在可以正确地生成AND匹配url。

这是错误的:

Django显然不知道它运行在一个子目录别名,这完全破坏了URL的生成和解析。

Django明白这一点,并透明地处理它。 服务器应该设置SCRIPT_NAME本身:你发现自己使用FORCE_SCRIPT_NAME的事实表明,问题在于你的Nginx配置,而不是在Django。

我怀疑这个问题是使用location ,而不是一个更合适的指令。 不幸的是,我不是Nginx / uwsgi的专家。 在Apache / mod_wsgi中,你可以这样做:

 WSGIScriptAlias /mysite /usr/local/django/mysite/apache/django.wsgi 

告诉mod_wsgi该网站从mysite开始,而不是根。 nginx / uwsgi几乎肯定有类似的命令。

如果在http://www.example.com/ (您的基本域)托管Django站点时,此Nginx位置块工作正常:

 location / { uwsgi_pass unix:/tmp/fancyprojectname.socket; include /etc/nginx/uwsgi_params; } 

然后这将工作在http://www.example.com/subpath/ (您的基本域的子路径):

 location /subpath { uwsgi_pass unix:/tmp/fancyprojectname.socket; uwsgi_param SCRIPT_NAME /subpath; # explicitly set SCRIPT_NAME to match subpath uwsgi_modifier1 30; # strips SCRIPT_NAME from PATH_INFO (the url passed to Django) include /etc/nginx/uwsgi_params; } 

…并且不需要在您的Django设置中设置FORCE_SCRIPT_NAME。

参考文献: