2014-10-26 131 views
4

我正在使用數據庫路由器,因此我有兩個數據庫用於我的應用程序。一個數據庫用於默認的django數據,另一個用於數據庫。無法使用數據庫路由器save_model保存

在我的管理員,我已經覆蓋save_model函數爲了保存created_by變量,但我無法做到這一點。

Cannot assign "<User: testuser>": the current database router prevents this relation. 

數據庫路由器:

from django.conf import settings 

    class DatabaseAppsRouter(object): 
     def db_for_read(self, model, **hints): 
      """Point all read operations to the specific database.""" 
      if settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label): 
       return settings.DATABASE_APPS_MAPPING[model._meta.app_label] 
      return None 

     def db_for_write(self, model, **hints): 
      """Point all write operations to the specific database.""" 
      if settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label): 
       return settings.DATABASE_APPS_MAPPING[model._meta.app_label] 
      return None 

     def allow_relation(self, obj1, obj2, **hints): 
      """Allow any relation between apps that use the same database.""" 
      db_obj1 = settings.DATABASE_APPS_MAPPING.get(obj1._meta.app_label) 
      db_obj2 = settings.DATABASE_APPS_MAPPING.get(obj2._meta.app_label) 
      if db_obj1 and db_obj2: 
       if db_obj1 == db_obj2: 
        return True 
       else: 
        return False 
      return None 

     def allow_syncdb(self, db, model): 
      """Make sure that apps only appear in the related database.""" 
      if model._meta.app_label in ['south']: 
       return True; 
      elif db in settings.DATABASE_APPS_MAPPING.values(): 
       return settings.DATABASE_APPS_MAPPING.get(model._meta.app_label) == db 
      elif settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label): 
       return False 
      return None 

管理:

class SomeEntityAdmin(admin.ModelAdmin): 
    def save_model(self, request, obj, form, change): 
     user = request.user._wrapped if hasattr(request.user,'_wrapped') else request.user 
     if not obj.created_by: 
      obj.created_by = user 
      obj.save() 

我甚至嘗試用save(using='thedb')定義不同的數據庫,但不工作的。我的數據庫路由器錯了嗎?

回答

5

您遇到的問題來自存儲在兩個不同數據庫中的對象之間存儲關係的困難。在你的例子中,你表示你已經創建了一個數據庫來存儲所有的Django貢獻對象,其中包括由auth應用創建的User對象。同時,第二個模型的對象將被存儲在一個完全獨立的獨立數據庫中。當您嘗試創建存儲在一個數據庫中的新對象與User對象之間的關係時,您正在嘗試跨數據庫關係。

跨數據庫關係是一個難題,在Django中使用多個數據庫時尚未解決。如果您想了解關於此問題的更多信息,請參閱the Django documentation has a brief note about this problem(爲清晰起見,請在下面複製)。

Django目前不支持跨越多個數據庫的外鍵或多對多關係。如果您使用路由器將模型分區到不同的數據庫,則由這些模型定義的任何外鍵和多對多關係必須位於單個數據庫內部。

這是因爲參照完整性。爲了維護兩個對象之間的關係,Django需要知道相關對象的主鍵是有效的。如果主鍵存儲在單獨的數據庫中,則無法輕鬆評估主鍵的有效性。

如果您將Postgres,Oracle或MySQL與InnoDB一起使用,這將在數據庫完整性級別執行 - 數據庫級別的關鍵約束會阻止創建無法驗證的關係。但是,如果您在MyISAM表中使用SQLite或MySQL,則不存在強制的參照完整性;因此,您可能能夠「僞造」跨數據庫外鍵。但是,這種配置並未得到Django的正式支持。

+1

這一切都有道理。所以我顯然沒有別的選擇,只能回到一個數據庫。 – JavaCake 2014-10-27 07:40:17

+0

優秀評論。我發現有關這些問題的信息太少。但我不想倒退。 @JavaCake,之後你有幸運嗎? – 2016-10-13 21:12:33