介绍
authenticate原本是账号和密码登录,在密码对给出的用户名合法的情况下返回一个 User 对象。 如果密码不合法,authenticate()返回None。重写该方法后,实现输入账号、邮箱、手机号等多种方式登录验证。
需要注意的是在重写authenticate时,要加入request:
def authenticate(self, request, username=None, password=None, **kwargs)
Code
views
class LoginView(View):
# 直接调用get方法免去判断
def get(self, request):
# render就是渲染html返回用户
# render三变量: request 模板名称 一个字典写明传给前端的值
redirect_url = request.GET.get('next', '')
return render(request, "login.html", {
"redirect_url": redirect_url
})
def post(self, request):
# 类实例化需要一个字典参数dict:request.POST就是一个QueryDict所以直接传入
# POST中的usernamepassword,会对应到form中
login_form = LoginForm(request.POST)
# is_valid判断我们字段是否有错执行我们原有逻辑,验证失败跳回login页面
if login_form.is_valid():
# 取不到时为空,username,password为前端页面name值
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
# 成功返回user对象,失败返回null
user = authenticate(request, username=user_name, password=pass_word)
# 如果不是null说明验证成功
if user is not None:
# 只有当用户激活时才给登录
if user.is_active:
# login_in 两参数:request, user
# 实际是对request写了一部分东西进去,然后在render的时候:
# request是要render回去的。这些信息也就随着返回浏览器。完成登录
login(request, user)
# 跳转到首页 user request会被带回到首页
# 增加重定向回原网页。
redirect_url = request.POST.get('next', '')
if redirect_url:
return HttpResponseRedirect(redirect_url)
# 跳转到首页 user request会被带回到首页
return HttpResponseRedirect(reverse("index"))
# 即用户未激活跳转登录,提示未激活
else:
return render(
request, "login.html", {
"msg": "用户名未激活! 请前往邮箱进行激活"})
# 仅当用户真的密码出错时
else:
return render(request, "login.html", {"msg": "用户名或密码错误!"})
# 验证不成功跳回登录页面
# 没有成功说明里面的值是None,并再次跳转回主页面
else:
return render(
request, "login.html", {
"login_form": login_form})
settings
# Application definition 注册我们的app
# 设置邮箱和用户名均可登录
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend',
)
views
class CustomBackend(ModelBackend):
"""
实现用户名邮箱均可登录
继承ModelBackend类,因为它有方法authenticate,可点进源码查看
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
# 不希望用户存在两个,get只能有一个。两个是get失败的一种原因 Q为使用并集查询
user = UserProfile.objects.get(
Q(username=username) | Q(email=username) | Q(mobile=username))
# django的后台中密码加密:所以不能password==password
# UserProfile继承的AbstractUser中有def check_password(self,
# raw_password):
# if user.check_password(password):
return user
except Exception as e:
return None