我想创建一个简单用户和管理员都可以使用的控制面板。我有两个数据库。在admin_db中我存储管理员,在mysql_db中我有简单的用户。 admin的用户在admin_db和mysql_db中具有相同的用户名,但可能是不同的pass(出于安全性和其他原因)。
我的概念如下:
用户登录。如果admin_db中存在用户名,则也可以选择以admin身份登录(可能在html中添加另一个按钮)。否则只显示简单的用户选项。
我怎样才能做到这一点?目前我使用默认的@login_required
,但它只检查一个数据库,我不能在数据库之间切换..
我该怎么做以下的事情:
def login(db=default, username=None):
#check the authentication
......
logged_in = False
while not logged_in:
if logged_in_mysql:
if username in admin_db:
show button 'login_as_admin'
else:
continue as normal
else:
login(mysql_db)
.....
if user_clicks_login_as_admin:
login(admin_db, god)
答案 0 :(得分:2)
由于没有人回答,我自己找到了一个解决方案,并将其发布给任何有同样问题的人:
首先,我的settings.py
中有2个数据库:
settings.py
DATABASES = {
'default': {
'NAME': 'myadmin',
'ENGINE': 'django.db.backends.mysql',
'USER': 'root',
'PASSWORD': 'abc123',
'HOST': '127.0.0.1',
'PORT': '3306',
},
'mysql': {
'NAME': 'mydb',
'ENGINE': 'django.db.backends.mysql',
'USER': 'root',
'PASSWORD': 'abc123',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
概念是一个数据库中的用户也可以在管理员数据库中(反之亦然)。为了帮助django同时玩两个数据库,我必须创建一个路由器,它将django指向我的登录应用程序的正确数据库。我在项目根文件夹中创建了routers.py
:
routers.py
class LoginRouter(object):
"""
Router for routing login operations to mysql db
"""
def db_for_read(self, model, **hints):
"""
Point all operations on login models to mysql
"""
if model._meta.app_label == 'login':
return 'mysql'
return 'default'
def db_for_write(self, model, **hints):
"""
Point all operations on login models to 'mysql'
"""
if model._meta.app_label == 'login':
return 'mysql'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Allow any relation if a both models in login app
"""
if obj1._meta.app_label == 'login' and obj2._meta.app_label == 'login':
return True
# Allow if neither is login app
elif 'mysql' not in [obj1._meta.app_label, obj2._meta.app_label]:
return True
return False
def allow_syncdb(self, db, model):
if db == 'mysql' or model._meta.app_label == "login":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
我还必须将以下行添加到settings.py
DATABASE_ROUTERS = ['routers.LoginRouter']
现在,如果您拥有与经典django用户身份验证不同的身份验证,则必须创建身份验证后端。我不得不这样做,因为我的另一个数据库包含一个名为name的字段,它是身份验证的“用户名”。请注意,在我的模型中我有很多表,这就是我调用dovecot.Users的原因(我需要这里的Users表)所以再次在我的根文件夹中我创建了一个backends.py
并添加了以下内容:
backends.py
#my custom model from my outer db
from login import models as dovecot
class EmailAuthBackend(object):
"""
Email Authentication Backend
Allows a user to sign in using an email/password pair rather than
a username/password pair.
"""
def authenticate(self, username=None, password=None):
""" Authenticate a user based on email address as the user name. """
try:
user = dovecot.Users.objects.get(name=username)
if self.check_password(password, user):
return user
except dovecot.Users.DoesNotExist:
return None
def get_user(self, user_id):
""" Get a User object from the user_id. """
try:
return dovecot.Users.objects.get(pk=user_id)
except dovecot.Users.DoesNotExist:
return None
然后我添加到我的settings.py
以下(记住优先级很重要!当django在后端成功时,它将不再继续。我稍后会提到我如何检查两个dbs):
settings.py
AUTHENTICATION_BACKENDS = ('backends.EmailAuthBackend', 'django.contrib.auth.backends.ModelBackend')
所以现在我创建了一个应用程序,其中django可以检查两个数据库以查看用户是否存在并对其进行身份验证..但我还想查看mail_db中的用户是否也具有管理员权限..所以在我的{ {1}}在我的登录应用程序中,我创建了一个login_user:
views.py
现在您登录用户,同时检查两个dbs中是否存在该用户。如果两者都存在用户,则可以提供管理员登录:)
希望能帮助有类似问题的人。我在互联网上搜索了一段时间,但找不到完整的解决方案,所以我决定把它放在这里供将来参考。我希望我没有忘记任何事情或犯过任何错误