版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzyaiwl/article/details/89421531
登陆模块在后端需要接收三个参数,分别是账号、密码、是否记住标志。为了实现这个三个参数的正确,需要给这三个参数写一个form,并在里面实现各个验证逻辑。记住和不记住的区别在于session的保存有效期,不记住就将session设置为0,即浏览器关闭就失效,记住标志可以将session有效期设为一个礼拜或两个礼拜都行。
在前端页面,可以使用模板语言,将用户是否登陆的状态,给予其不同的页面展示,对于该用户是否拥有管理后台权限,同等如此。
登陆验证api
1、接收前端传来的参数,用户名、电话、密码、确认密码、短信验证码 2、form表单的构造,并实现相应的验证逻辑 3、验证成功后,将用户名、密码、电话保存在数据库中,用到用户模型的creat_user方法 4、注册成功后,自动跳转到已登陆状态
- form表单
class Login_form(forms.Form):
user_account = forms.CharField(max_length=20,min_length=5,required=True)
password = forms.CharField(max_length=20,min_length=6,required=True,error_messages={
'max_length':'密码长度不能低于6位','min_length':'密码名长度不能大于20位','required':'密码不能为空'
})
remember_me = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
"""
"""
self.request = kwargs.pop('request', None)
super().__init__(*args, **kwargs)
def clean_user_account(self):
user_acc = self.cleaned_data.get('user_account')
if not user_acc:
raise forms.ValidationError('账号不能为空')
if not re.match('^1[3-9]/d{9}$',user_acc) and (len(user_acc)<5 or len(user_acc)>20):
raise forms.ValidationError("账号不符合格式")
return user_acc
def clean(self):
cleaned_data = super().clean()
user_info = cleaned_data.get('user_account')
passwd = cleaned_data.get('password')
holded_login = cleaned_data.get('remember_me')
user_queryset = Users.objects.filter(Q(mobile = user_info)|Q(username = user_info))
if not user_queryset.first():
raise forms.ValidationError("此账号不存在,请重新输入")
else:
user = user_queryset.first()
if user.check_password(passwd):
if holded_login:
self.request.session.set_expiry(60*15*24*60)
else:
self.request.session.set_expiry(0)
login(self.request,user)
else:
raise forms.ValidationError("密码不正确,请重新输入")
- 视图函数
class Register(View):
"""
"""
def get(self,request):
return render(request, 'users/register.html')
def post(self,request):
json_data = request.body
if not json_data:
return to_json_data(errno= Code.PARAMERR,errmsg=error_map[Code.PARAMERR])
dict_data = json.loads(json_data.decode('utf-8'))
form = User_form(data=dict_data)
if form.is_valid():
#将用户名、密码保存到数据库中
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
mobile = form.cleaned_data.get('mobile')
user = Users.objects.create_user(username=username,password=password,mobile=mobile)
user.save()
login(request, user)
return to_json_data(errmsg="恭喜您,注册成功!")
else:
error_list = []
for item in form.errors.get_json_data().values():
# error_list = error_list.append(item[0].get('message'))
error_list.append(item[0].get('message'))
err_msg_str = '/'.join(error_list) # 拼接错误信息为一个字符串
return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)
- 路由设置
urlpatterns = [
path('login/',views.Login.as_view(),name='login'),
]
- Ajax部分代码
let SdataParams = {
"user_account": sUserAccount,
"password": sPassword,
"remember_me": bStatus
};
// 创建ajax请求
$.ajax({
// 请求地址
url: "/users/login/", // url尾部需要添加/
// 请求方式
type: "POST",
data: JSON.stringify(SdataParams),
// 请求内容的数据类型(前端发给后端的格式)
contentType: "application/json; charset=utf-8",
// 响应数据的格式(后端返回给前端的格式)
dataType: "json",
})
.done(function (res) {
if (res.errno === "0") {
// 注册成功
message.showSuccess('恭喜你,登录成功!');
setTimeout(function () {
// 注册成功之后重定向到打开登录页面之前的页面
window.location.href = document.referrer;
}, 1000)
} else {
// 登录失败,打印错误信息
message.showError(res.errmsg);
}
})
.fail(function(){
message.showError('服务器超时,请重试!');
});
-
踩坑记录: 1、form表单的request从哪里来?可以在视图调用form表单传参过去,form表单在__init__方法里进行接收 2、login方法登陆传入的两个参数request和user是位置参数,不是默认参数。
登出api
登出api实现对现有用户session的清除。
1、对于登陆,注册接口是否展示,取决于当前是否登陆if user.is_authenticated 2、对于隐藏的后台管理接口是否展示,取决于当前用户是否有登陆的后台的权限user.is_staff 3、对于登出功能是否展示,取决于当前是否有用户已经登陆if user.is_authenticated 4、当前用户名展示{{ user.username }}
- 视图函数
class Login_out(View):
"""
"""
def get(self,request):
logout(request)
return redirect(reverse('users:login'))
-
路由设置
urlpatterns = [
path('loginout/',views.Login_out.as_view(),name='log_out'),
]