用户登录
js
$(function () {
let $login = $('.form-contain'); // 获取登录表单元素
// 登录逻辑
$login.submit(function (e) {
// 阻止默认提交操作
e.preventDefault();
// 获取用户输入的账号信息
let sUserAccount = $("input[name=telephone]").val(); // 获取用户输入的用户名或者手机号
// 判断用户输入的账号信息是否为空
if (sUserAccount === "") {
message.showError('用户账号不能为空');
return
}
// 判断输入手机号格式或者用户名格式是否正确
if (!(/^\w{5,20}$/).test(sUserAccount) || !(/^\w{5,20}$/).test(sUserAccount)) {
message.showError('请输入合法的用户账号:5-20个字符的用户名或者11位手机号');
return
}
// 获取用户输入的密码
let sPassword = $("input[name=password]").val(); // 获取用户输入的密码
// 判断用户输入的密码是否为空
if (!sPassword) {
message.showError('密码不能为空');
return
}
// 判断用户输入的密码是否为6-20位
if (sPassword.length < 6 || sPassword.length > 20) {
message.showError('密码的长度需在6~20位以内');
return
}
// 获取用户是否勾许"记住我",勾许为true,不勾许为false
let bStatus = $("input[type='checkbox']").is(":checked"); // 获取用户是否选择记住我,勾上代表true,没勾上代码false
// 发起登录请求
// 创建请求参数
let SdataParams = {
"user_account": sUserAccount,
"password": sPassword,
"remember_me": bStatus
};
// 创建ajax请求
$.ajax({
// 请求地址
// url: "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 = '/news/index';
}, 1000)
} else {
// 登录失败,打印错误信息
message.showError(res.errmsg);
}
})
// .fail(function(){
// message.showError('服务器超时,请重试!');
// });
});
// get cookie using jQuery
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// Setting the token on the AJAX request
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
});
form表单进行数据清洗
#创建一个登录的表单
class LoginForm(forms.Form):
#用户名
user_account = forms.CharField()
#密码
password = forms.CharField(label='密码', max_length=20, min_length=6,
error_messages={"min_length": "密码长度要大于6", "max_length": "密码长度要小于20",
"required": "密码不能为空"})
#是否打钩记住密码
remember_me = forms.BooleanField(required=False)
#复回,用来接受从视图函数传过来的vrequest函数
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(LoginForm, self).__init__(*args, **kwargs)
#数据清洗
def clean_user_account(self):
"""
"""
user_info = self.cleaned_data.get('user_account')
if not user_info:
raise forms.ValidationError("用户账号不能为空")
if not re.match(r"^1[3-9]\d{9}$", user_info) and (len(user_info) < 5 or len(user_info) > 20):
raise forms.ValidationError("用户账号格式不正确,请重新输入")
return user_info
def clean(self):
cleaned_data = super().clean()
# 获取清洗之后的用户账号
user_info = cleaned_data.get('user_account')
# 获取清洗之后的密码
passwd = cleaned_data.get('password')
hold_login = cleaned_data.get('remember_me')
# 在form表单中实现登录逻辑,
#判断输入的用户名和手机号是否有用户
user_queryset = Users.objects.filter(Q(mobile=user_info) | Q(username=user_info))
if user_queryset:
#获取第一个用户
user = user_queryset.first()
#检查用户输入的密码是否和数据库的密码是否一致
if user.check_password(passwd):
#如果勾选记住密码,则就保存session
if hold_login: # redis中保存session信息
self.request.session.set_expiry(None)
login(self.request, user)
else:
self.request.session.set_expiry(0)
else:
raise forms.ValidationError("密码不正确,请重新输入")
else:
raise forms.ValidationError("用户账号不存在,请重新输入")
视图函数
#定义一个类视图
class LoginView(View):
def get(self, request):
return render(request, 'users/login.html')
def post(self, request):
json_data = request.body
if not json_data:
return to_json_data(errno=Code.PARAMERR, errmsg="输入的数据有误,请重新输入")
# 将json转化为dict
dict_data = json.loads(json_data.decode('utf8')) # 没有解码,会产生bug
form = forms.LoginForm(data=dict_data, request=request)
if form.is_valid():
return to_json_data(errmsg="恭喜您,登录成功!")
else:
# 定义一个错误信息列表
err_msg_list = []
for item in form.errors.get_json_data().values():
err_msg_list.append(item[0].get('message'))
err_msg_str = '/'.join(err_msg_list) # 拼接错误信息为一个字符串
return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)
相应的html修改
{% if user.is_authenticated %}//判断是否登录
<div class="author">
<i class="PyWhich py-user"></i>
<span>{{ user.username }}</span>/显示用户名
<ul class="author-menu">
{% if user.is_staff %}//判断是否是超级管理员
<li><a href="javascript:void(0);">后台管理</a></li>
{% endif %}
<li><a href="{% url 'logout' %}">退出登录</a></li>
</ul>
</div>
{% else %}
<div>
<i class="PyWhich py-user"></i>
<span>
<a href="{% url 'login' %}" class="login">登录</a> / <a href="{% url 'register' %}"
class="reg">注册</a>
</span>
</div>
{% endif %}
用户退出
用户退出就是将session清除即可
类视图操作为:
#退出登录
class LogoutView(View):
def get(self,request):
logout(request)
return redirect(reverse('login'))