简体   繁体   English

基于当前登录用户的Django数据库路由

[英]Django Database routing based on current user logged in

In a view class, you could call self.request.user and perform actions based on that.view类中,您可以调用self.request.user并基于此执行操作。 In my case, I would like to be able to switch databases depending on the current user logged in. Is there anyway to inject a self.request call into the db_for_read() and db_for_write() methods like in the following?在我的情况下,我希望能够根据当前登录的用户切换数据库。无论如何,是否可以将self.request调用注入到db_for_read()db_for_write()方法中,如下所示?

class DataBaseRouter(object):

    def db_for_read(self, model, **hints):
        user = self.request.user
        if user.id == 1:
            return "master"
        return "default"

    def db_for_write(self, model, **hints):
        user = self.request.user
        if user.id == 1:
            return "master"
        return "default"

You can use a RouterMiddlewear to check if what user is logged in and then redirect all the queries to a particular database of your choice, this would be help full if you are using view based execution of the queries.您可以使用RouterMiddlewear来检查用户是否登录,然后将所有queries重定向到您选择的特定数据库,如果您使用view based的查询执行,这将非常RouterMiddlewear

class RouterMiddleware (object):

    def process_view( self, request, view_func, args, kwargs ):
        # Check the user logged in
        user = self.request.user
        # Call your functions to set the database by passing the user.id



    def process_response( self, request, response ):
        # Make the database to default here if you wish to use it no longer

        return response


class DataBaseRouter(object):

    def db_for_read(self, model, user_id=None, **hints):
       if user.id == 1:
            return "master"
        return "default"

    def db_for_write(self, model, user_id=None, **hints):
        if user.id == 1:
            return "master"
        return "default"

Here is the link that I have modified for your requirement.这是我根据您的要求修改的链接

Make sure you add the the RouterMiddleware to your MIDDLEWARE_CLASSES .确保将RouterMiddleware添加到MIDDLEWARE_CLASSES

Try this django dynamic db router package .试试这个django 动态数据库路由器包 its very simple.它非常简单。 install it and configure and use as below.安装它并配置和使用如下。

settings.py设置.py

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'my_local_database',
    'USER': 'postgres',
    'PASSWORD': 'my-pass',
    'HOST': '127.0.0.1',
    'PORT': '5432',
},
'master': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'my_master_database',
    'USER': 'postgres',
    'PASSWORD': 'my-pass',
    'HOST': 'example.com',
    'PORT': '5432',
},
}
DATABASE_ROUTERS = ['dynamic_db_router.DynamicDbRouter']

my_app/views.py my_app/views.py

from dynamic_db_router import in_database

from my_app.models import MyModel

def index(request):
     #Picking the DB based on logged in user or you can do this in middile ware as well.
     use_db = "default"
     user = self.request.user
     if user.id == 1:
        use_db = "master"
     # Fetching data from selected databases. 
     with in_database(use_db):
         input = MyModel.objects.filter(field_a="okay")
         output = complex_query_function(input)

To resolve this, I created a new model with just one userid field.为了解决这个问题,我创建了一个只有一个userid字段的新模型。 Then in router when specifying db for read and write, I get the data from that model so I don't need any request argument.然后在路由器中指定 db 进行读写时,我从该模型中获取数据,因此我不需要任何请求参数。
And I just added a short ajax code in my base template so whenever my website is opened it gets the userid from request.user and change the model row so current user id is changed like so.我刚刚在我的基本模板中添加了一个简短的 ajax 代码,所以每当我的网站打开时,它都会从 request.user 获取用户 ID 并更改模型行,因此当前用户 ID 会像这样更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM