一、功能需求分析
1、登陆功能分析
1.1、流程
1.2、功能
二、登陆页面
1、接口设计
1.1、接口说明
类目 |
说明 |
请求方式 |
GET |
url |
/user/login/ |
参数 |
无参数 |
1.2、返回结果
登陆界面
三、登陆功能
1、业务流程
1.1、参数校验
1.2、登陆逻辑
1. 在session中保存状态
2. 根据记住我选项,进行有效期的设置,(session_id)
2、接口设计
2.1、接口说明
类目 |
说明 |
请求方式 |
POST |
url |
/user/login/ |
参数 |
表单 |
2.2、参数说明
参数名 |
类型 |
是否必须 |
描述 |
account |
字符串 |
是 |
用户输入的账号,手机号码或用户名 |
password |
字符串 |
是 |
用户输入的密码 |
remember |
字符串 |
否 |
用户是否勾选免登陆 |
2.3、返回结果
{
errno:'0',
errmsg:'ok',
}
登陆界面
2、后台代码
2.1、视图
class LoginView(View):
"""
登陆视图
url:/user/login/
"""
def get(self,request):
return render(request,'user/login.html')
def post(self,request):
#1、先校验
form = LoginForm(request.POST,request=request)
if form.is_valid():
return json_response(errmsg='恭喜登陆成功!')
else:
# 将表单报错信息进行拼接
err_msg_list = []
for item in form.errors.values():
err_msg_list.append(item[0])
err_msg_str = '/'.join(err_msg_list)
return json_response(errno=Code.PARAMERR, errmsg=err_msg_str)
2.2、form表单
class LoginForm(forms.Form):
"""
登陆校验表单
"""
account = forms.CharField(error_messages={'required':'账户不能为空'})
password = forms.CharField(label='密码', max_length=20, min_length=6, error_messages={
'max_length': '密码长度小于20!',
'min_length': '密码长度大于6!',
'required': '密码不能为空!',
})
remember = forms.BooleanField(required=False)
def __init__(self,*arge,**kwargs):
self.request = kwargs.pop('request', None)
super().__init__(*arge,*kwargs)
def clean_account(self):
"""
校验用户名
:return:
"""
account = self.cleaned_data.get('account')
if not re.match(r'^1[3-9]\d{9}$',account) and (len(account) >20 or len(account) < 5):
raise forms.ValidationError('用户账号格式不正确,请重新输入!')
return account
def clean(self):
"""
校验用户名密码,并实现登陆逻辑
:return:
"""
clean_data = super().clean()
account = clean_data.get('account')
password = clean_data.get('password')
remember = clean_data.get('remember')
#登陆逻辑
#判断是否用户名密码是否匹配
#先找到用户,在判断校验这个密码是否匹配
#select * from tb_user where mobile=account or username=account
user_qureyset = User.objects.filter(Q(mobile=account)|Q(username=account))
if user_qureyset:
user = user_qureyset.first()
if user.check_password(password):
#是否免登陆,remember
if remember:
#免登陆14天
self.request.session.set_expiry(14*24*60*60)
else:
#关闭浏览器即清除登陆状态
self.request.session.set_expiry(0)
#登陆
login(self.request,user)
else:
raise forms.ValidationError('账户密码错误')
else:
raise forms.ValidationError('用户账户不存在,请重新输入!')
return clean_data
2.3、js
$(function () {
let $loginBtn = $('.login-btn'); // 获取登录按钮元素
$loginBtn.click(function (e) {
e.preventDefault(); // 阻止默认提交
// 1.校验账户
let sAccount = $('input[name="account"]').val();
if (sAccount === ''){
message.showError('用户账户不能为空');
return
}
if(!(/^\w{5,20}$/).test(sAccount) && !(/^1[3-9]\d{9}$/).test(sAccount)){
message.showError('用户账户格式不正确,请求重新输入');
return
}
// 2.校验用户输入密码
let sPassword = $('input[name="password"]').val();
if(sPassword === ''){
message.showError('用户密码不能为空');
return
}
// 3.获取用户是否勾选'记住我',勾选为true,否则为false
let bRemember = $('input[name="remember"]').is(':checked');
// 4.发送ajax
$.ajax({
url: '/user/login/',
data: {
account: sAccount,
password: sPassword,
remember: bRemember
},
type: 'POST',
dataType: 'json',
success: function (res) {
if(res.errno === '0'){
message.showSuccess('恭喜, 登录成功!');
setTimeout(function () {
//注册成功之后重定向到打开登录页面之前的页面
if(!document.referrer || document.referrer.includes('/user/login/') || document.referrer.includes('/user/register/')){
window.location.href = '/'
}else {
window.location.href = document.referrer
}
}, 1000)
}else{
message.showError(res.errmsg)
}
},
error: function (xhr, msg) {
message.showError('服务器超时,请重试')
}
});
});
});
2.4、url
path('login/', views.LoginView.as_view(), name='login'),
四、登出功能
1、接口设计
1.1、接口说明
类目 |
说明 |
请求方式 |
GET |
url |
/user/logout/ |
参数 |
无参数 |
1.2、返回结果
登出
2、后台代码
2.1 、视图
from django.contrib.auth import logout
class LogoutView(View):
def get(self,request):
logout(request)
return redirect(reverse('user:login'))
2.2、url
path('logout/', views.LogoutView.as_view(), name='logout'),