django配置連線多個數據庫,和把應用名字在admin後臺顯示為中文
在專案tt下新建兩個app,分別為app01、app02。配置app01使用default節點資料庫;app02使用hvdb節點資料庫(也可以配置app01下的model既使用default,也可以使用hvdb資料庫)
1.編輯settings.py,新增多個數據庫:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'testly', 'USER': 'root', 'PASSWORD': '123456789', 'HOST':'192.168.1.1', 'PORT':'3306', }, 'hvdb':{ #配置第二個資料庫節點名稱 'ENGINE': 'django.db.backends.mysql', 'NAME': 'testdjango', #第二個資料庫的名稱 'USER': 'root', 'PASSWORD': '123456789', 'HOST':'192.168.1.1', 'PORT':'3306', } }
Django 要求default 資料庫必須定義,但是如果不會用到,其引數字典可以保留為空。若要這樣做,你必須為你的所有的應用的模型建立DATABASE_ROUTERS,包括正在使用的contrib 中的應用和第三方應用。
default留空寫法:
'default': {},
2.新增資料庫路由表
在tt目錄下新建檔案db_router.py,內如如下。該檔案用來對資料庫進行自動路由,可以根據每個model的app_label來指定使用某個DB。
注:可以定義多個Router,由於此處的app01使用default資料庫,所以在此無需指定default節點的資料庫路由。
# -*- coding: UTF-8 -*- class app02Router(object): #配置app02的路由,去連線hvdb資料庫 """ A router to control all database operations on models in the app02 application.""" def db_for_read(self, model, **hints): """ Attempts to read app02 models go to hvdb DB. """ if model._meta.app_label == 'app02': #app name(如果該app不存在,則無法同步成功) return 'hvdb' #hvdb為settings中配置的database節點名稱,並非db name。dbname為testdjango return None def db_for_write(self, model, **hints): """ Attempts to write app02 models go to hvdb DB. """ if model._meta.app_label == 'app02': return 'hvdb' return None def allow_relation(self, obj1, obj2, **hints): """ Allow relations if a model in the app02 app is involved. 當 obj1 和 obj2 之間允許有關係時返回 True ,不允許時返回 False ,或者沒有 意見時返回 None 。 """ if obj1._meta.app_label == 'app02' or \ obj2._meta.app_label == 'app02': return True return None def allow_migrate(self, db, model): """ Make sure the app02 app only appears in the hvdb database. """ if db == 'hvdb': return model._meta.app_label == 'app02' elif model._meta.app_label == 'app02': return False def allow_syncdb(self, db, model): #決定 model 是否可以和 db 為別名的資料庫同步 if db == 'hvdb' or model._meta.app_label == "app02": return False # we're not using syncdb on our hvdb database else: # but all other models/databases are fine return True return None # class app01Router(object): # """ # A router to control all database operations on models in the # aew application. # """ # def db_for_read(self, model, **hints): # """ # Attempts to read aew models go to aew DB. # """ # if model._meta.app_label == 'app01': # return 'default' # return None # def db_for_write(self, model, **hints): # """ # Attempts to write aew models go to aew DB. # """ # if model._meta.app_label == 'app01': # return 'default' # return None # def allow_relation(self, obj1, obj2, **hints): # """ # Allow relations if a model in the aew app is involved. # """ # if obj1._meta.app_label == 'app01' or obj2._meta.app_label == 'app01': # return True # return None # def allow_migrate(self, db, model): # """ # Make sure the aew app only appears in the aew database. # """ # if db == 'default': # return model._meta.app_label == 'app01' # elif model._meta.app_label == 'app01': # return False # return None
3.編輯settings.py,新增路由:
注:由於此處的app01使用default資料庫,所以在此無需指定default節點的資料庫路由。
DATABASE_ROUTERS = ['tt.db_router.app02Router'] #tt為當前專案名稱,db_router為上一步編寫的db_router.py檔案,app02Router為Router #DATABASE_ROUTERS = ['tt.db_router.app02Router','tt.db_router.app01Router'] #如果定義了多個Router,在此就需要分別指定。注意:這個是有順序的(先匹配上的規則,就先生效)
4.為每個app的model分別指定所需要連線的資料庫:
通過對每個model指定好對應的app_label,使其通過Router去連線相應的資料庫。
編輯app02下的models.py,為app02下的model mtable01指定連線hvdb節點資料庫,內容如下:
class mtable01(models.Model): name=models.CharField(max_length=100,primary_key=True,unique=True) ip=models.GenericIPAddressField() rating = models.IntegerField() def __str__(self): return self.name class Meta: app_label = 'app02' #定義該model的app_label ordering = ['name'] 使用migrate命令同步資料庫:
編輯app01下的models.py:
class tb05(models.Model): #該model使用default資料庫 name=models.CharField(max_length=100,primary_key=True,unique=True) ip=models.GenericIPAddressField() rating = models.IntegerField() def __str__(self): return self.name class Meta: #app_label = 'app01' #由於該model連線default資料庫,所以在此無需指定 ordering = ['name']
也可以為app01下的model指定連線hvdb資料庫,內容如下:
class tb2(models.Model): name=models.CharField(max_length=100,primary_key=True,unique=True) ip=models.GenericIPAddressField() rating = models.IntegerField() def __str__(self): return self.name class Meta: app_label = 'app02' ordering = ['name']
為app01下的tb02指定使用hvdb資料庫,同時自定義表名稱為‘mytable’,不使用預設的表名稱app02_tb06,不便於區分
class tb06(models.Model): name=models.CharField(max_length=100,primary_key=True,unique=True,db_column='mycname') #使用db_column自定義欄位名稱 ip=models.GenericIPAddressField() rating = models.IntegerField() def __str__(self): return self.name class Meta: db_table = 'mytable' #自定義表名稱為mytable verbose_name = '自定義名稱' #指定在admin管理介面中顯示的名稱 app_label = 'app02' ordering = ['name']
5.同步資料庫:
migrate管理命令一次操作一個數據庫。預設情況下,它在default 資料庫上操作,但是通過提供一個 --database 引數,告訴migrate同步一個不同的資料庫。
1)同步default節點資料庫,只執行不帶 --database引數的命令,不對其他資料庫進行同步
python manage.pymigrate
python manage.py makemigrations
python manage.pymigrate
2)同步hvdb節點資料庫:
python manage.pymigrate --database=hvdb
python manage.py makemigrations
python manage.pymigrate --database=hvdb
結果:
testdjango資料庫(hvdb節點)下的app02_mtable01表對應app02下的mtable01模型
testdjango資料庫(hvdb節點)下的app02_tb2表對應app01下的tb2模型
testly資料庫(default節點)下的app01_tb05表對應app01下的tb05模型
【讓應用在admin後臺中顯示為中文】
from os import path from django.apps import AppConfig VERBOSE_APP_NAME = "YOUR VERBOSE APP NAME HERE" def get_current_app_name(file): return path.dirname(file).replace('\\', '/').split('/')[-1] class AppVerboseNameConfig(AppConfig): name = get_current_app_name(__file__) verbose_name = u'配方管理' default_app_config = get_current_app_name(__file__) + '.__init__.AppVerboseNameConfig'