我想在开发服务器的子目录别名中运行一个简单的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。
参考文献: