【问题标题】:Is it possible for Django to use the same link and a database for each client?Django 是否可以为每个客户端使用相同的链接和数据库?
【发布时间】:2018-11-16 11:07:32
【问题描述】:

Django 是否可以为每个客户端使用相同的链接和数据库?

您好,我是 Django 新手,有一个问题。 我将一个 PHP 系统带到 Django,其中所有客户端都使用相同的链接来访问系统,但每个客户端都有其包含用户、访问组等的数据库。 在自定义登录屏幕中,他们通知他们的客户端 ID、用户和密码进行身份验证,其中客户端 ID 始终是数据库的名称。

我做了以下代码来更改可能是错误的数据库连接:

def change_db (self):
    connections ['default']. settings_dict ['NAME'] = self.db
    return True

代码甚至交换了我想要访问的数据库,但是在我的本地机器上使用 runserver 进行测试,如果另一个客户端同时访问,例如在另一个浏览器中,它会取代另一个客户端。

有没有人遇到过或者有解决的想法?搜了下路由器,不知道能不能解决我的问题,或者切换连接去掉其他客户端也有同样的问题。

感激不尽。

【问题讨论】:

  • 据我所知,这些设置是不可变的。在运行时更改设置会很危险,因为有几个 Django 部分不是为处理此类更改而设计的。
  • 我明白,django 没有更好的方法来选择用户将使用的数据库吗?也许每个会话都不会更改设置?
  • 是的,例如,您可以使用数据库路由:docs.djangoproject.com/en/2.0/topics/db/multi-db/#using-routers
  • 我会尝试使用路由器,如果你得到结果我会通知你

标签: python django django-2.0


【解决方案1】:

根据文档,您不应该在运行时编辑 settings.py,但是 你试过this吗?

【讨论】:

  • 请不要链接到答案,把相关内容放在你的答案中。
  • 我只是为了测试而尝试了这个,所以我支持根据登录用户切换连接的最佳解决方案,而不会出现在另一个客户端登录时全局交换数据库的问题。
【解决方案2】:

我想我解决了我的问题,我找到了一个对我非常有用的链接:

dynamically set database based on request in django

它使用中间件来获取响应的工作人员提到的连接和路由器,在它需要子域的情况下,我在其中进行了一些更改以获取已经解决我的情况的前缀,在帮助下这个链接:

Django URL with dynamic prefix

关注代码:

from django.utils.deprecation import MiddlewareMixin
from django.contrib.sessions.middleware import SessionMiddleware
import re
import threading 

request_cfg = threading.local()

#Middleware
class RouterMiddleware(MiddlewareMixin):

    def process_request(self, request):
        words = request.get_full_path()
        db_name = words.split('/')[1]
        request_cfg.cfg = db_name
        return None

    def process_view(self, request, view_func, view_args, view_kwargs):
        cliente = view_kwargs.get('cliente')
        if cliente:
            request.cliente = cliente
            view_kwargs.pop('cliente')
            return view_func(request, *view_args, **view_kwargs)

    def process_response(self, request, response):
        if hasattr(request_cfg, 'cfg'):
            del request_cfg.cfg
        return response

#Router
class DatabaseRouter (object):
    def _default_db(self):
        if hasattr(request_cfg, 'cfg'):
            return request_cfg.cfg
        else:
            return 'default'

    def db_for_read(self, model, **hints):
        return self._default_db()

    def db_for_write(self, model, **hints):
        return self._default_db()

感谢任何试图帮助我的人:)

【讨论】:

    猜你喜欢
    • 2012-04-12
    • 2023-03-09
    • 1970-01-01
    • 2015-04-14
    • 2018-09-06
    • 2021-03-31
    • 2012-05-12
    • 1970-01-01
    • 2019-10-21
    相关资源
    最近更新 更多