假如在一個django項目中使用到了不僅一個數據庫, 其實這在大一點的工程中很常見,好比主從庫mysql
那麼會涉及到以下一些東西sql
1, 定義數據庫
在settings中的DATABASE中定義會使用到的數據,好比除default外咱們還定義了一個 searchdjango
1 DATABASE = { 2 'default':{ 3 'ENGINE': 'django.db.backends.sqlite3', 4 'NAME': 'path/to/database.sqllite3', 5 'USER':'', 6 'PASSWORD':'', 7 'HOST': '', 8 'PORT':'', 9 }, 10 'search':{ 11 'ENGINE': 'django.db.backends.mysql', 12 'NAME': 'search_db', 13 'USER':'db_user', 14 'PASSWORD':'p@55word', 15 'HOST': '192.168.12.186', 16 'PORT':'', 17 } 18 }
2, 使用app
會產生數據庫操做的幾個地方ui
假若有Model對象 objspa
它的save()會執行 INSERT 或 UPDATEcode
它的 delete() 會執行 DELETEorm
咱們拿到一個obj,或者建立一個新的obj後,使用非default db時, 參數中傳進usingsqlite
obj = Person(name='wy', uid=530) obj.save(using='search') obj.delete(using='search')
經過manager拿到的都是QuerySet, 它對應數據庫中的一個集合, 對應的語句是 SELECT
QuerySet有using方法, 指定去SELECT的數據庫, 而QuerySet有一組方法是返回QuerySet對象的,因此只要在這個調用鏈中使用 using 就行
Person.objects.all().using('search').filter(uid__gt=100)
而manager自己提供了一個方法using, 這麼定義的
def using(self, *args, **kwargs): return self.get_queryset().using(*args, **kwargs)
因此上面那行代碼等效於
Person.objects.using('search').filter(uid__gt=100)
有時候咱們會在manager層面設置使用的數據庫. 好比對自定義的manager.
自定義的manager常見的一個狀況是重寫get_queryset()方法, 好比一個lady_manager,它能夠重寫get_queryset()只返回全部lady,而後再在這個基礎上filter...
其實manager返回的QuerySet的_db是manager本身的_db傳過去的, 而manager有 db_manager()這個方法來設置自身的_db
def db_manager(self, using): obj = copy.copy(self) obj._db = using return obj
因此只要這麼用就好, 假如Person有一個自定義manager ladies
Person.ladies.db_manager('search').all()
3, admin使用多數據庫
admin是django自帶的一個app,那它涉及的是,讀一個Model的全部對象(讀一張表SELECT), 增長,刪除,那麼重寫admin.ModelAdmin的以下幾個作這幾件事方法就行了
class MultiDBModelAdmin(admin.ModelAdmin): # A handy constant for the name of the alternate database. using = 'other' def save_model(self, request, obj, form, change): # Tell Django to save objects to the 'other' database. obj.save(using=self.using) def delete_model(self, request, obj): # Tell Django to delete objects from the 'other' database obj.delete(using=self.using) def get_queryset(self, request): # Tell Django to look for objects on the 'other' database. return super(MultiDBModelAdmin, self).get_queryset(request).using(self.using) def formfield_for_foreignkey(self, db_field, request=None, **kwargs): # Tell Django to populate ForeignKey widgets using a query # on the 'other' database. return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs) def formfield_for_manytomany(self, db_field, request=None, **kwargs): # Tell Django to populate ManyToMany widgets using a query # on the 'other' database. return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
如上代碼摘自django文檔,關於 formfield_for_foreignkey 和 formfield_for_manytomany 還沒細研究
把上面的類定義放到本身的代碼中,而後本身的ModelAdmin從它派生就好了, using中指定要使用的數據庫, 如
class PersonAdmin(MultiDBAdmin): pass admin.site.register(PersonAdmin, Person)
-----------------------
參考: