Skip to main content
 首页 » 编程设计

python之Django之使用多个数据库进行身份验证时出现全局名称错误

2024年10月01日43cmt

我有一个用于登录系统的基本应用程序,非常非常基本的工作正常,但现在我试图让它与另一个数据库一起工作,这并不像我想象的那么容易。我在阅读时发现我需要一个数据库路由器才能使其与我的第二个数据库一起工作,所以我试了一下。

这是我得到的:

settings.py

DATABASES = { 
    'default': { 
        'ENGINE': 'django.db.backends.sqlite3', 
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 
    }, 
    'db2':{ 
        'ENGINE': 'django.db.backends.sqlite3', 
        'NAME': os.path.join(BASE_DIR, 'login.db'), 
    } 
} 
MIDDLEWARE_CLASSES = [ 
    'django.middleware.security.SecurityMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'myapp.middleware.CustomerMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
] 
 
DATABASE_ROUTERS = ['myapp.routers.MultiCustomerRouter'] 

routers.py

from middleware import my_local_global 
 
class MultiCustomerRouter(object): 
    def db_for_read(self, model, **hints): 
        return my_local_global.db2 

中间件.py

from threading import local 
 
my_local_global = local() 
 
class CustomerMiddleware(object): 
    def process_request(self, request): 
        my_local_global.db2 = get_db2(request) # my database name is db2 

我在关注这个 Django Authenticate Backend Multiple Databases在我运行 python manage.py runserver 之后我得到了这个错误:

NameError at /

global name 'get_db2' is not defined

我怎样才能处理这个问题以使其在我的数据库 db2 中按预期工作?

views.py

def login_view(request): 
    print(request.user.is_authenticated()) 
    title = 'login' 
    form = UserloginForm(request.POST or None) 
    if form.is_valid(): 
        username = form.cleaned_data.get("username") 
        password = form.cleaned_data.get("password") 
        user = authenticate(username=username,password=password) 
        login(request,user) 
        print(request.user.is_authenticated()) 
        return redirect('first_view') 
    return render(request, "form.html",{"form":form,"title":title}) 

基本上我想要实现的是使用 db2 而不是默认的进行身份验证。

请您参考如下方法:

我不认为你链接到的问题是在做你想做的同样的事情。如果您只想使用不同的数据库进行身份验证,则不需要线程局部变量或在请求对象上设置变量 - 这个问题是关于每个客户使用不同的数据库(这将取决于登录的客户等) ).

你的错误是因为你正在调用一个你没有在任何地方定义的函数 get_db2 - 你显然只是复制/粘贴了另一个问题的大部分代码而不理解它的作用.

您可能想阅读 Django docs在数据库路由器上,它有一个示例似乎完全符合您的要求(您不需要中间件)——这直接取自前面链接的页面:

class AuthRouter(object): 
    """ 
    A router to control all database operations on models in the 
    auth application. 
    """ 
    def db_for_read(self, model, **hints): 
        """ 
        Attempts to read auth models go to auth_db. 
        """ 
        if model._meta.app_label == 'auth': 
            return 'auth_db' 
        return None 
 
    def db_for_write(self, model, **hints): 
        """ 
        Attempts to write auth models go to auth_db. 
        """ 
        if model._meta.app_label == 'auth': 
            return 'auth_db' 
        return None 

但是,针对不同的功能使用不同的数据库很复杂,因此需要的不仅仅是上述内容。阅读文档了解更多详情。