Django Database routing based on current user logg

2019-05-11 01:46发布

In a view class, you could call self.request.user and perform actions based on that. 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?

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"

2条回答
Juvenile、少年°
2楼-- · 2019-05-11 02:15

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.

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.

查看更多
孤傲高冷的网名
3楼-- · 2019-05-11 02:17

Try this django dynamic db router package. its very simple. install it and configure and use as below.

settings.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

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)
查看更多
登录 后发表回答