Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Database routing based on current user logged in

Tags:

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"
like image 222
Lorenzo Avatar asked Sep 06 '16 17:09

Lorenzo


People also ask

What is using self _DB in Django?

This is used in case you have multiple databases by which you define which database you need to use for operation. An example user. save(using=self. _db) is usually defined as "default" from your database configuration in settings.py .

Can we use 2 databases in Django?

Django's admin doesn't have any explicit support for multiple databases. If you want to provide an admin interface for a model on a database other than that specified by your router chain, you'll need to write custom ModelAdmin classes that will direct the admin to use a specific database for content.

What database does Django use by default?

By default, the configuration uses SQLite. If you're new to databases, or you're just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won't need to install anything else to support your database.


1 Answers

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.

like image 179
kt14 Avatar answered Sep 26 '22 16:09

kt14