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

Lor*_*nzo 5 django python-3.x django-rest-framework

view课堂上,您可以self.request.user基于此调用和执行操作。就我而言,我希望能够根据当前登录的用户切换数据库。无论如何,是否可以将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"
Run Code Online (Sandbox Code Playgroud)

kt1*_*t14 3

您可以使用 aRouterMiddlewear检查用户是否登录,然后将所有用户重定向到您选择的特定数据库,如果您正在使用查询的执行,queries这将很有帮助。view based

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"
Run Code Online (Sandbox Code Playgroud)

这是我根据您的要求修改的链接。

确保将 the 添加RouterMiddleware到您的MIDDLEWARE_CLASSES.

  • @kt14嗨,我真的不明白如何将 user.id 注入到路由器类中。在链接的片段中,我们使用 threading.local() 来共享此内容,但我无法使其在 django 2.1.4 上工作。也许这有一些改变? (3认同)
  • @kt14你是如何在`db_for_read`方法中传递`user`对象的?如果不使用“threading”全局对象,这是不可能的(如链接所示)。!这可以在会话之间共享!。请解释一下`RouterMiddleware`和`DataBaseRouter`之间的联系 (2认同)