2017-07-08 64 views
4

我已經在服務器上的子目錄(dns_name_of_my_page/notes)上部署了我的Django項目。我在這個項目中的應用程序可以通過dns_name_of_my_page/notes/app /訪問。不幸的是,如果整個Django項目位於託管服務器上public_html的子目錄「註釋」中,則管理站點無法正常工作。當我進入管理站點(dns_name_of_my_page/notes/admin /)時,會重定向到沒有子目錄名稱(dns_name_of_my_page/adminlogin /?next = // admin /)的URL,這是不可接受的。它應該是相當dns_name_of_my_page /筆記/後臺管理/下一= /筆記/管理/Django在子目錄中 - 管理站點不工作

這裏是項目我的網址的配置:

urlpatterns = [ 
    url(r'^/?app/?', include('app.urls')), 
    url(r'^/?$', views.index, name='index'), 
    url(r'^/?admin/?', admin.site.urls), 
] 

這是我在我的應用程序的URL的配置:

urlpatterns = [ 
    url(r'^$', views.index, name='index'), 
    url(r'^(?P<num>[0-9]+)/?', views.num, name='num'), 
] 

我已經嘗試設置

FORCE_SCRIPT_NAME = '/notes/' 

SUB_SITE = "/notes/" 

在settings.py中,但它沒有幫助我。

你有沒有在子目錄中運行Django應用程序的這種問題?

+0

您初始化項目的日誌記錄?當你想訪問管理頁面時會得到什麼錯誤?靜態文件的工作? – hansTheFranz

+1

我認爲你的'url(r'^ /?admin /?',admin.site.urls),'應該是'url(r'^ admin /',admin.site.urls),''不帶'?'。 .. –

+0

同意。Django可以爲你處理尾隨斜線。 https://docs.djangoproject.com/en/1.10/ref/settings/#append-slash –

回答

1

我今天被發現了這個問題,雖然有很多類似的問題[1],但是我的解決方案的經驗給我的答案有點混合。

您的問題中缺少的一個細節是您正在使用的服務器設置。爲了解釋我的解決方案,有助於理解它如何與Django方面結合使用。

我一直在解決的問題包括訪問Django的管理員(以及大多數其他應用程序,如Auth)的問題是讓服務器充當多個獨立django項目的主機。目標是以http://my.server.com/project_name/foo/bar/ [2]開頭的URI。就每個項目而言,它都在my.server.com上運行,並且正在處理/ foo/bar(大多數生產/單一應用程序系統會出現這種情況,使用manage.py runserver進行本地開發)

我正在使用NGinx作爲監聽端口80和443的反向代理服務器。在該服務器中,我有一個location設置,以便爲每個子項目代理Nginx服務+ Gunicorn。

nginx的默認位置的配置是這樣的:

location /project_name { 
    proxy_set_header X-Forwarded-Protocol $scheme; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header Host $http_host; 
    proxy_set_header X-Scheme $scheme; 
    proxy_set_header X-Forwarded-For $remote_addr; 

    proxy_pass http://localhost:7001/; 
} 

的設置每個項目自身的nginx + gunicorn服務是不是這個話題特別相關,但你可以看到它呈現在自己的本地服務端口。

該配置將提供http://my.server.com/foo/bar/的有效請求。這使我們現在有信心讓Django爲它在輸出中生成的所有URL添加/ project_name /前綴。

要做到這一點,有需要已覆蓋關鍵設置了一把,它們是:

USE_X_FORWARDED_HOST = True 
FORCE_SCRIPT_NAME = '/project_name/' 

這會導致Django的尊重頭改變了nginx的沿着通過,並且也觸發它自己的用於在模板中重寫{% url name %}標籤的輸出的過程。

SESSION_COOKIE_PATH = '/project_name/' 

這應該有助於分離出該域名上多次登錄,而且意味着你可以記錄在一個項目,但沒有其他(或混淆它)。

STATIC_FILES_ROOT='\path\on\disk\as\in\your\nginx\config\for\static\' 
STATIC_FILES_URL='/project_name/static/' 
MEDIA_FILES_ROOT='\path\on\disk\as\in\your\nginx\config\for\media\' 
MEDIA_FILES_URL='/project_name/media/' 

這些處理`{%static blah%}類型模板標記和文件服務。

LOGIN_REDIRECT_URL='/project_name/' 
LOGOUT_REDIRECT_URL='/project_name/' 

這些處理使用驗證模塊登錄/退出服務,並確保它向用戶發送回上登錄或註銷的項目站點的根目錄的結果。您可以輕鬆地定製這些你自己的需要,使用URL-conf的風格正則表達式的字符串,比如我們會在您的網站urls.py這條線的管理頁面

ADMIN_URL=r'^admin/' 

此設定對以下做包括:

url(settings.ADMIN_URL, include(admin.site.urls)), # default=r'^admin/' 

這裏一個關鍵的細節是,沒有前面的/在正則表達式,否則會試圖迫使它回到主機名,因而深受FORCE_SCRIPT_NAME指定的變化會工作。

另外,注意不要在以/開頭的模板中包含任何硬編碼的網址(相對或其他),因爲這將不會被Django模板輸出更改捕獲。

按照這種方法,我已經能夠在三個不同的系統中部署這些項目中的每一個,其中兩個涉及它們作爲該域或服務端口上唯一的django應用程序運行,剩下的一個就是這個共享域設置,並且不需要改變每個位置上的設置值。


考慮用自己的代碼樣本這種方法,我建議你在尋找變化:

urlpatterns = [ 
    url(r'^admin/?', admin.site.urls), 
    url(r'^app/?', include('app.urls')), 
    url(r'^$', views.index, name='index'), 
] 

要助手的搜索和匹配順序,我已經重新安排管理員來首先,空白/ home/root匹配模板最後到達。否則,您的FORCE_SCRIPT_NAME設置處於正確的軌道上。


[1]例如multiple instances of django on a single domain; Is it possible to host multiple django projects under the same domain?; how to deploy django under a suburl behind nginx

[2]默認服務器實際上也在處理SSL翻譯,因爲服務在https上呈現,但內部localhost端口(隱藏在機器防火牆後面)僅處理http。