具有多个自定义数据库管理员的多数据库路由

时间:2018-02-16 04:53:11

标签: django python-3.x

我正在尝试使用自定义管理数据库的多个数据库。我正在使用路由。当我将我的默认数据库留空时。它显示错误 settings.DATABASES配置不正确。请提供ENGINE值。 但是在填充默认数据库中的详细信息时,它可以正常工作,因为它使用两个URL的默认设置。

项目settings.py

'default': {

},
'users': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'users',
    'USER': '****',
    'PASSWORD': '****',
    'HOST': 'localhost',
    'PORT': '5432',
},
'rsa': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'rsa',
    'USER': '****',
    'PASSWORD': '****',
    'HOST': 'localhost',
    'PORT': '5432',
},

DATABASE_ROUTERS = ['antef.router.DBRouter']
DATABASE_APPS_MAPPING = {
    'login': 'users',
    'rsa': 'rsa'
}

项目urls.py

from django.contrib import admin
from django.urls import path, include

admin.autodiscover()

urlpatterns = [
    path('login/', include('login.urls')),
    path('rsa/', include('rsa.urls')),
]

项目routers.py

from django.conf import settings
class DBRouter:

def db_for_read(self, model, **hints):
    """"Point all read operations to the specific database."""
    return settings.DATABASE_APPS_MAPPING.get(model._meta.app_label, None)

def db_for_write(self, model, **hints):
    """Point all write operations to the specific database."""
    return settings.DATABASE_APPS_MAPPING.get(model._meta.app_label, 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_migrate(self, db, app_label, model_name=None, **hints):
    """Make sure that apps only appear in the related database."""
    if db in settings.DATABASE_APPS_MAPPING.values():
        return settings.DATABASE_APPS_MAPPING.get(app_label) == db
    elif app_label in settings.DATABASE_APPS_MAPPING:
        return False
    return None

登录urls.py

from login.admin import admin_site
from django.urls import path, include

urlpatterns = [
    path('admin/', admin_site.urls),
]

登录admin.py

from django.contrib import admin
from login.models import user_detail

admin_site = admin.AdminSite('users')
admin_site.register(user_detail)

登录models.py

from django.db import models

class user_detail(models.Model):
    u_name = models.CharField(max_length=200)
    u_email = models.EmailField(max_length=225, unique=True)
    u_passwd = models.CharField(max_length=225)
    u_img = models.CharField(max_length=200)
    u_created = models.CharField(max_length=200)
    u_app = models.CharField(max_length=200)

    class Meta:
        app_label = 'login'

    def __str__(self):
        return self.u_email

rsa应用程序的相同文件,但具有不同的模型类

1 个答案:

答案 0 :(得分:0)

最后使用路由中间件。在项目文件夹中创建单个router.py文件。请务必将中间件添加到settings.py文件

router.py

import threading

request_cfg = threading.local()


class RouterMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

def __call__(self, request):
    return self.get_response(request)

def process_view(self, request, view_func, view_args, view_kwargs):
    path = request.path
    if 'users' in path:
        request_cfg.db = 'users'
    elif 'rsa' in path:
        request_cfg.db = 'rsa'

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


class DBRouter(object):
    def db_for_read(self, model, **hints):
    if model._meta.app_label == 'users':
        return 'users'
    elif model._meta.app_label == 'rsa':
        return 'rsa'
    elif hasattr(request_cfg, 'db') and 'users' in request_cfg.db:
        return 'users'
    elif hasattr(request_cfg, 'db') and 'rsa' in request_cfg.db:
        return 'rsa'

def db_for_write(self, model, **hints):
    if model._meta.app_label == 'users':
        return 'users'
    elif model._meta.app_label == 'rsa':
        return 'rsa'
    elif hasattr(request_cfg, 'db') and 'users' in request_cfg.db:
        return 'users'
    elif hasattr(request_cfg, 'db') and 'rsa' in request_cfg.db:
        return 'rsa'

def allow_relation(self, obj1, obj2, **hints):
    if obj1._meta.app_label == 'users' or obj2._meta.app_label == 'users':
        return True
    elif obj1._meta.app_label == 'rsa' or obj2._meta.app_label == 'rsa':
        return True

    return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label == 'users':
        return db == 'users'
    elif app_label == 'rsa':
        return db == 'rsa'
    elif hasattr(request_cfg, 'db') and 'users' in request_cfg.db:
        return 'users'
    elif hasattr(request_cfg, 'db') and 'rsa' in request_cfg.db:
        return 'rsa'