2017-04-03 93 views
6

我設置了基於URL的數據庫路由,其靈感來源於this答案,以便爲不同的項目/數據庫使用相同的應用程序。項目不需要共享任何數據,訪問控制由每個項目自行管理,我需要每個項目的管理站點。與原始文章中一樣,我使用數據庫路由器和中間件來確定從請求路徑使用哪個數據庫,例如/test/process/1將被路由到數據庫test/default/process/2到數據庫default基於URL的數據庫路由

import threading 
from django.conf import settings 

request_cfg = threading.local() 

class RouterMiddleware(object): 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     path = request.path.lstrip('/').split('/') 
     if path[0] in settings.DATABASES: 
      request_cfg.db = path[0] 

    def process_response(self, request, response): 
     if hasattr(request_cfg, 'db'): 
      del request_cfg.db 
     return response 

class DatabaseRouter(object): 
    def _default_db(self): 
     if hasattr(request_cfg, 'db') and request_cfg.db in settings.DATABASES: 
      return request_cfg.db 
     else: 
      return 'default' 

    def db_for_read(self, model, **hints): 
     return self._default_db() 

    def db_for_write(self, model, **hints): 
     return self._default_db() 

URL模式然後需要被擴展到包括其指的是特定的數據庫子路徑。我這樣做是在這樣的項目級別urls.py硬編碼的URL:

urlpatterns = [ 
    url(r'^default/admin/', include(admin.site.urls)), # does not work 
    url(r'^test/admin/', include(admin.site.urls)), # does not work 
    url(r'^default/', include('logbook.urls', namespace='anything')), 
    url(r'^test/', include('logbook.urls', namespace='anything else'))] 

我承認,這是不是很漂亮,但我不希望有管理超過幾數據庫的更多。有趣的是,命名空間參數是什麼並不重要,但必須給出。該應用程序的原始名稱空間爲logbook,它用於在應用程序的視圖和模板中反轉網址。

然後,在應用程序級別的urls.py APP_NAME已經被定義(和等於原來的命名空間):

app_name = 'logbook' 

urlpatterns = [ 
    url(r'^$', views.redirect_index, name='index'), 
    url(r'^(?P<date>[0-9]{4}[0-9]{2})/$', views.Index.as_view(), name='index'), 
..... 

在視圖我添加了一個current_app=request.resolver_match.namespace kwarg到的reverse()每個呼叫作爲在Django文檔中解釋。在模板中解析URL並不需要任何修改。

總的來說,這工作得很好但有兩個例外:

  • 網址倒車任何的管理意見,將永遠解決在urls.py中的第一項
  • 我不能讓它與django.contrib.auth.middleware.AuthenticationMiddleware大多工作,我認爲因爲LOGINLOGIN_REDIRECT是常數。

我想知道這是否是一種乾淨的方法,以及是否有解決上述兩個例外的問題。如果不是,那麼更好的解決方案是什麼?

+2

你如何部署?在我看來,最好的做法是在服務器配置中對網址進行分類,例如apache,然後使用兩個完全獨立的django wsgi應用程序,所以你不必擔心這些。我不認爲django管理員應用程序可以很好地處理多個數據庫。如果您不需要多個用戶數據庫,您可以通過將管理和授權等數據庫集中在一個數據庫中來獲得一些里程數。 – daphtdazz

+0

我還沒有想過部署,我正在使用python webserver。無論如何,我預計會有更多問題,例如與媒體文件一樣,正如你所說,似乎管理應用程序不會與多個數據庫一起工作。我可能會把所有數據都放在一個數據庫中。謝謝你的想法。 –

回答

2

這是您正在尋找的文章。

Django Multi DB Documentation

它說明了如何設置您的多個數據庫,以及管理控制檯與它一起工作。正如它說的,你需要爲你的第二個數據庫(非默認數據庫)創建一個自定義模型,並使用文檔中給出的方法進行註冊。

+0

我之前閱讀過這個頁面,但顯然不是關於管理界面的部分。但是,身份驗證中間件的問題仍然存在。目前我決定放棄這個想法,併爲所有項目製作大型數據庫。 –