2012-07-02 118 views
14

我想在開發服務器上的子目錄別名中運行簡單的測試項目。基本設置是一個nginx,具有將子目錄中的所有內容傳遞給wsgi應用程序的位置。通過子路徑中的nginx + uwsgi運行django應用程序

Django顯然不知道它運行在一個子目錄別名中,它完全破壞了URL的生成和解析。
我無法在文檔中找到任何類似前綴的設置,而我的谷歌fu也沒有那麼多幫助......所以我在這裏問了一下。

我唯一發現的是設置FORCE_SCRIPT_NAME,它至少修復了URL生成。 (請參閱:http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath
不幸的是,這並不能解決urlconf解析問題,即使提到的網站提示。

是否有可能在子目錄別名中運行django應用程序,如果是這樣,如何?

nginx的配置:

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

我認爲正在發生的事情:當管理員用正則表達式「^管理員」和實際的URL是「fancyprojectname /管理/」,Django的不正確匹配的URL開始,即使是SCRIPT_NAME組。

解決方案

所以,它的確是與SCRIPT_NAME的問題。

WSGI specification說以下內容:

SCRIPT_NAME 對應於應用程序對象,使得應用程序知道它的虛擬 「位置」請求URL的「路徑」的初始部分。如果應用程序 對應於服務器的「根」,則這可能是空字符串。

PATH_INFO 請求URL的「路徑」的其餘部分,指定應用程序中請求目標的虛擬「位置」。如果請求URL以應用程序根目標爲目標,並且 沒有結尾斜槓,則這可能是 一個空字符串。

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。

+0

請看看https://stackoverflow.com/a/40496307/1588163你會發現有更新的方式來完成這項 – clapas

+0

[見:如何用uwsgi安裝Django應用程序](https://stackoverflow.com/questions/19475651/how-to-mount-django-app-with-uwsgi) –

回答

7

這是錯誤的:

Django的顯然不明白,它在子目錄中的別名,這完全破壞URL生成和解析運行。

Django 確實瞭解並處理它透明。服務器應該設置SCRIPT_NAME本身:您發現自己使用FORCE_SCRIPT_NAME的事實表明問題在於您的Nginx配置,而不是在Django中。

我懷疑問題是使用location,而不是一個更合適的指令。不幸的是,我不是Nginx/uwsgi的專家。在阿帕奇/ mod_wsgi的,你可以這樣做:

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

告訴mod_wsgi的該網站開始於mysite,而不是根源。幾乎可以肯定,nginx/uwsgi有類似的命令。

+3

好吧,我試着用「uwsgi_param SCRIPT_NAME/fancyprojectname;」在nginx中,這似乎「工作」,因爲我現在可以在設置中註釋掉FORCE_SCRIPT_NAME,並且URL生成正確 - 但這仍然不能修復URL匹配。我會在問題中追加當前的url配置。 – Strayer

+5

看起來它現在正在工作 - SCRIPT_NAME不是eneugh,它將「uwsgi_modifier1 30」設置爲「」;儘管如此。我不知道這個設置是幹什麼的,但是當我發現我會再次更新問題並接受這個作爲有效答案。感謝指針! – Strayer

+0

謝謝@Strayer。它爲我工作:) –

5

如果託管在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。

參考文獻:

+0

謝謝,現在我有[Hatta wiki](http://hatta-wiki.org/)在子路徑中運行在nginx下。 –

+0

不要忘記將「env = DJANGO_SETTINGS_MODULE = your_app.settings」添加到您的uwsgi.ini文件中。 –

相關問題