1. 程式人生 > >django使用多資料庫,以及admin管理使用的方法。

django使用多資料庫,以及admin管理使用的方法。

django中可以從多個數據庫中讀寫資料。

由於業務需要,開發中遇到了需要讀寫另一個數據庫的情況。

以下是工作時的遇到問題的解決方法:

django多資料庫的配置:

1. 在資料庫配置欄位,增加需要連線的資料庫

在settings.py檔案下找到

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ire_test',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'genius': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ire_my',
        'USER': 'root',
        'PASSWORD': '123456',
        "HOST": "127.0.0.1",
        'PORT': '3306',
    },
}
2. 編寫需要呼叫這個資料庫的model

在models.py檔案下找到

@python_2_unicode_compatible
class StockCode(models.Model):
    com_code = models.IntegerField('公司程式碼', null=True, db_column='COMCODE')
    stock_code = models.CharField('股票程式碼', max_length=12, null=True, db_column='STOCKCODE')

    def __str__(self):
        return "{self.com_code} {self.stock_code}".format(self=self)

    @staticmethod
    def get_com_code(stock_code):
        sc = StockCode.objects.filter(stock_code=stock_code).first()
        if sc:
            return sc.com_code
        else:
            return None


    class Meta:
        # app_label = 'convertfirst'
        db_table = 'stk_code'
        verbose_name = '公司資訊'
        verbose_name_plural = '公司資訊'
        managed = False

首先需要給model的欄位設定好對映的資料庫欄位db_column,並在meta中設定好連線的db_table,managed=False為同步資料庫時不同步這個model

這裡需要注意的是,model中的欄位可以只設置需要的欄位,而不需要資料庫中所有欄位。

3.編寫資料庫路由

由於使用了多個數據庫,所以我們需要編寫一個數據庫路由來告訴django需要對哪些model進行orm時對於那個資料庫。

新建一個db_router.py檔案,編寫一個轉發器

# coding=utf-8
from __future__ import (unicode_literals, absolute_import)

genius_models = (
    'ConvertFirst',
    'StockCode',
)

class ConvertFirstRouter(object):
    """
    A router to control all database operations on models in the
    watchlist application.
    """

    def db_for_read(self, model, **hints):
        """
        Attempts to read watchlist models go to genius DB.
        """
        if model.__name__ in genius_models:
            return 'genius' 
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write watchlist models go to genius DB.
        """
        if model.__name__ in genius_models:
            return 'genius' 
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the watchlist app is involved.
        """
        if obj1.__class__.__name__ in genius_models or obj2.__class__.__name__ in genius_models:
            return True
        return None

    def allow_migrate(self, db, model):
        """
        Make sure the watchlist app only appears in the watchlist database.
        """
        if db in genius_models:
            return model._meta.app_label in genius_models
        elif model._meta.app_label in genius_models:
            return False

其中genius_model元組中的classname為需要特殊處理的model類,可自行定義(這裡主要是需要特殊處理的model與不需要特殊處理的model存在一個app的models.py檔案下,所以這裡不能使用app_label來區分,具體方法有很多)。

通過上述檔案中的方法可以告訴django在處理這些model的orm關係時,使用settings裡那個資料庫進行連線。

4. admin裡的運用

admin裡的運用就和再次modeladmin一樣了。