在Django

时间:2019-05-13 19:05:49

标签: django python-3.x

我正在开发一个Django应用程序,其中我需要多个数据库,每个系统用户一个数据库。为此,我定义了这样的数据库:


DATABASES = {
    'default': {},
    'primary': {
        'NAME': 'primary',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
    'user1': {
        'NAME': 'user1',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
    'user2': {
        'NAME': 'user2',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
}

其中数据库user1user2primary结构的副本。

假设我创建了两个超级用户,分别具有登录名“ superuser1”和“ superuser2”。如何定义当记录“ superuser1”时,数据库“ user1”中的数据已更改,当记录“ superuser2”时,数据库“ user2”中的数据已更改?

1 个答案:

答案 0 :(得分:0)

此逻辑可能会遍及您的应用程序。实际上,您将需要创建一个将使用用户实例的函数,然后返回将映射到数据库的字符串:

DATABASE_USER_MAP = {
    'username1': 'user1',
}

def get_database(user):
    return settings.DATABASE_USER_MAP.get(user.username, 'default')

def some_view(request):
    data = Data.objects.using(get_database(request.user)).all()
    ...

一旦完成类似的工作,就可以将数据库确定逻辑移到中间件中,并将其设置在request上,以便可以:

def some_view(request):
    data = Data.objects.using(request.db).all()
    ...

与此相关的主要问题是,它将默认为primary,而不是错误地强迫您在编写查询时保持细致。

您可能想要追求的另一种途径是深入研究Django的代码库,以查看数据库路由器的工作方式以及是否可以将请求作为提示发送到路由器。我对此一无所知,所以我不知道是否有可能。但是,如果可能的话,就可以消除我提出的问题。