【问题标题】:Multi-database routing with multiple custom database admins具有多个自定义数据库管理员的多数据库路由
【发布时间】:2018-02-16 04:53:11
【问题描述】:

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

项目设置.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')),
]

Project 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 应用的文件相同,但模型类不同

【问题讨论】:

    标签: django python-3.x


    【解决方案1】:

    终于用路由中间件解决了。在项目文件夹中创建了单个 router.py 文件。一定要在settings.py文件中添加中间件

    路由器.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'
    

    【讨论】:

      猜你喜欢
      • 2016-05-12
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 2011-12-24
      • 2020-10-03
      • 2012-07-18
      相关资源
      最近更新 更多