我正在为一所学校创建一个django项目,主要有三种用户 - 家长,老师和学生。对于家长和老师,我希望他们使用电子邮件登录(他们目前正在使用遗留系统的电子邮件登录)。
然而,对于学生,我希望他们使用传统的用户名方法登录(因为年幼的孩子没有电子邮件)。这是可以在Django中做到还是只允许一个用户身份验证模型?
答案 0 :(得分:2)
您可以创建单独的onload
,仅用于通过电子邮件进行记录,并将其添加到设置中的AuthenticationEmailBackend
。通过这种方式,如果以前的AUTHENTICATION_BACKENDS
身份验证失败,则会使用不同的AUTHENTICATION_BACKENDS
作为备选方案。
应用/ auth.py 强>
AUTHENTICATION_BACKENDS
<强> settings.py 强>
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
class AuthenticationEmailBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
如果您在列表中保留默认AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
...
"app.auth.AuthenticationEmailBackend",
)
,则用户可以通过用户名或电子邮件登录。
答案 1 :(得分:2)
对于Django 3.0:
# myapp/backends.py
from django.contrib.auth.backends import BaseBackend
from .models import MyUser
class EmailAuthenticationBackend(BaseBackend):
def authenticate(self, request, **kwargs):
email = kwargs['username'].lower() # If you made email case insensitive add lower()
password = kwargs['password']
try:
my_user = MyUser.objects.get(email=email)
except MyUser.DoesNotExist:
return None
else:
if my_user.is_active and my_user.check_password(password):
return my_user
return None
def get_user(self, user_id):
try:
return MyUser.objects.get(pk=user_id)
except MyUser.DoesNotExist:
return None
这适用于Django 2.0和以前的版本:
# myapp/backends.py
from django.contrib.auth.backends import ModelBackend
from .models import MyUser
class EmailAuthenticationBackend(ModelBackend):
def authenticate(self, request, **kwargs):
email = kwargs['username']
password = kwargs['password']
try:
my_user = MyUser.objects.get(email=email)
except MyUser.DoesNotExist:
return None
else:
if my_user.is_active and my_user.check_password(password):
return my_user
return None
(不确定扩展ModelBackend是否是一个好主意,您可以创建自己的类)
然后,对于两个版本:
# settings.py
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"myapp.backends.EmailAuthenticationBackend",
]
答案 2 :(得分:1)
一个简单的后端,允许您使用电子邮件地址或用户名登录。
它应与另一个后端结合使用以检查权限:
settings.py:
AUTHENTICATION_BACKENDS = (
'myproject.accounts.backends.EmailOrUsernameModelBackend',
'django.contrib.auth.backends.ModelBackend' )
帐户/后端。py:
from django.conf import settings
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
if '@' in username:
kwargs = {'email': username}
else:
kwargs = {'username': username}
try:
user = User.objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
,并且不区分大小写:
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
# user_model = get_user_model()
if '@' in username:
# kwargs = {'email': username}
field = 'email'
else:
# kwargs = {'username': username}
field = 'username'
try:
case_insensitive_username_field = '{}__iexact'.format(field)
user = User._default_manager.get(**{case_insensitive_username_field: username})
# user = User.objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
答案 3 :(得分:1)
似乎 request 参数:
def authenticate(self, request, username=None, password=None)
根据Django documentation中的说法。
答案 4 :(得分:0)
在models.py
中class UserDet(models.Model):
email = models.EmailField(max_length=20)
userName = models.CharField(max_length=20)
在views.py
中def user_login(request):
response_data={}
if request.session.has_key('login_id'): #If user already logedin send to dashboard else check userid and password
return render(request, '/dashboard.html')
else:
if request.method == 'POST': # If request method is post then only process request
#print('here in login')
try:
username = request.POST.get('username')
password = request.POST.get('pass')
if '@' in username: #check for email
try:
for u in UserDet.objects.filter(email=username):
#username=u['userName']
username=u.userName
except:
response_data['code']=1000
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
if not request.POST.get('rememberme', None): # check user select the remember me or not if yes then create session that expire after long time
#print('seeing it 0')
request.session.set_expiry(0)
user = authenticate(username=username, password=password) # Check user exist or not
if user: #if user exist then
if user.is_active: #check user is active or not if active then successfully loged in else send error
login(request,user)
update_last_login(None, user)
request.session['login_id'] = user.id
response_data['code']=800
response_data['status']='success'
return HttpResponse(json.dumps(response_data), content_type="application/json")
#return render(request, '/dashboard.html')
else:
response_data['code']=900 #Error for User is not active
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
#return HttpResponse("Your account was inactive.")
else: #Error or Invalid username or password
#print("Someone tried to login and failed.")
#print("They used username: {} and password: {}".format(username,password))
response_data['code']=1000
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
except:
response_data['code']=1001
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
else: #Return to index
return redirect('/', {})