登陆功能
本功能需求:
-使用Ajax提交数据信息
-渲染用户名密码不符合要求的错误信息
-登陆后可以实现登出当前账号
拓展需求:
-登陆时判断用户是否被冻结
-登陆时使用登陆表单进行验证
一、添加路由
在urls.py中添加
1、登陆路由
path('login/', views.login, name='login'),
2、生成随机验证码路由
path('get_valid_code/', views.get_valid_code, name='get_valid'),
3、登出当前用户路由
path('logout/', views.logout, name='logout'),
二、添加视图函数
在views.py中
1、先导入一些需要的模块
from django.contrib import auth
from django.contrib.auth import authenticate
2、然后添加视图函数login
def login(request):
if request.method == 'POST':
res = {'code': 100}
username = request.POST.get('username')
password = request.POST.get('password')
valid_code = request.POST.get('valid_code')
if request.session.get('valid_code').upper() == valid_code.upper() or valid_code == '123':
user = auth.authenticate(username=username, password=password)
freezed = models.UserInfo.objects.filter(username=username, is_active=0).first()
res['url'] = '/index/'
if freezed:
res['code'] = 105
res['msg'] = '账户被冻结'
if user:
auth.login(request, user)
res['msg'] = '登录成功'
else:
res['code'] = 101
res['msg'] = '用户名密码错误'
else:
res['code'] = 102
res['msg'] = '验证码错误'
return JsonResponse(res)
elif request.method == 'GET':
form = x_forms.FormLogin()
return render(request, 'Login.html', {'form': form})
else:
return HttpResponse('非法请求!')
其中涉及到一个手动添加登录验证码的操作
添加视图函数get_rgb(随机函数,利用RGB形成随机颜色)
和get_valid_code(获取随机验证码)
def get_rgb():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
def get_valid_code(request):
img = Image.new('RGB', (200, 38), get_rgb())
img_draw = ImageDraw.Draw(img)
img_font = ImageFont.truetype('./static/font/FZFenSTXJW.TTF', 25)
valid_code = ''
for i in range(5):
low_char = chr(random.randint(97, 122))
num_char = random.randint(0, 9)
upper_char = chr(random.randint(65, 90))
res = random.choice([low_char, num_char, upper_char])
valid_code += str(res)
img_draw.text((i * 40 + 10, 5), str(res), get_rgb(), img_font)
request.session['valid_code'] = valid_code
print(valid_code)
f = BytesIO()
img.save(f, 'png')
data = f.getvalue()
return HttpResponse(data)
(拓展)我们可以在x_forms,py的文件中加入一个表示登陆信息校验的类(FormLogin),用来校验登陆时从前端返回的字符串是否符合要求
class FormLogin(forms.Form):
username = forms.CharField(
required=True,
label='<i class="fa fa-user width-30" aria-hidden="true"></i>',
error_messages={
'required': '用户名不能为空'
},
widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入账号'}),
)
password = forms.CharField(
required=True,
label='<i class="fa fa-lock width-30" aria-hidden="true"></i>',
error_messages={
'required': '密码不能为空'
},
widget=widgets.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'}),
)
3、添加登出视图函数(logout)
def logout(request):
auth.logout(request)
return redirect(reverse('login'))
(拓展): 验证码暗门
这里的代码中
if request.session.get('valid_code').upper() == valid_code.upper() or valid_code == '123':
最后的123设置为方便开发者自己调试程序时使用,无论生成的随机验证码是什么,输入验证码123都可登陆,正式上线的话应该去除这个暗门
三、登录功能涉及的模型层操作
判断用户登录时使用扩写的UserInfo表中自带认证auth模块
user = authenticate(username=username, password=password)
(拓展)此处继承的原始User表中有个is_active字段,可以用来判断用户是否被冻结
freezed = models.UserInfo.objects.filter(username=username, is_active=0).first()
四、登录功能前端模板
1、在templates中的login.html中
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{% include 'template_static/css_base.html' %}
<style>
ul {
list-style: none
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="mt-5 mb-5"><br></div>
<div class="row mt-5 mb-5">
<div class="col-md-6 offset-md-3 card bg-white shadow-sm mr-3 my-img">
<div class="row">
<div class="col-md-8 card-body p-5 bg-white-7">
<div class="mt-5 mb-5"><br></div>
<h1 class="text-center mt-5 swiper-cube-shadow">欢迎回来</h1>
<form action="" method="post" class="mx-5 my-3">
{% csrf_token %}
{% for foo in form %}
<div class="input-group mt-2">
<div class="height-40 width-b100">
<div class="input-group-prepend">
<div class="input-group-text">
<label for="{{ foo.auto_id }}" class="mb-0">{{ foo.label|safe }}</label>
</div>
{{ foo }}
</div>
</div>
</div>
{% endfor %}
<div class="input-group mt-2">
<div class="input-group-prepend">
<div class="input-group-text radius-5">
<i class="fa fa-hand-o-right width-30" aria-hidden="true"></i>
</div>
</div>
<input type="text" class="form-control radius-5" id="valid_code" name="password"
placeholder="请输入验证码">
<img src="/get_valid_code/" height="38" width="200" id="valid_code_img"
class="ml-1 radius-5 pointer" title="点击刷新验证码">
</div>
<input type="button" class="btn btn-outline-primary btn-block mt-3 mb-5" value="登录" id="btn-login">
</form>
<div class="mt-5 mb-3"><br><br></div>
</div>
<div class="col-md-4 bg-black-4">
<div class="h-100 pt-5 text-center">
<h2 class="text-white ml-3 mt-5">还未注册?</h2>
<p class="text-white mb-5">立即注册,观看更多内容!</p>
<div class="mt-5 mb-5"><br><br><br><br><br><br></div>
<a href="{% url 'register' %}" class="btn btn-outline-light">去注册</a>
</div>
</div>
</div>
</div>
<div class="alert alert-warning ml-5 col-md-2 shadow-sm invisible max-height-240" id="tips">
<h4 class="alert-heading">温馨提示:</h4>
<hr>
<div class="d-none font-weight-bold m-3" id="tips1"></div>
<div class="d-none font-weight-bold m-3" id="tips2"></div>
<div class="d-none font-weight-bold m-3" id="tips3"></div>
</div>
</div>
</div>
<script>
$('#valid_code_img').click(function () {
var url = $("#valid_code_img")[0].src
$("#valid_code_img")[0].src = url + '?'
})
$('#btn-login').click(function () {
$('input').addClass('is-valid')
if ($('#id_username').val().length === 0) {
$('#id_username').removeClass('is-valid').addClass('is-invalid')
$('#tips').removeClass('invisible')
$("#tips1").text('请输入用户名').removeClass('d-none')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#id_username').removeClass('is-invalid').val('')
}, 1500)
}
$('#id_password').addClass('is-valid')
if ($('#id_password').val().length === 0) {
$('#id_password').removeClass('is-valid').addClass('is-invalid')
$('#tips').removeClass('invisible')
$("#tips2").text('请输入密码').removeClass('d-none')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#id_password').removeClass('is-invalid').val('')
}, 1500)
}
$.ajax({
url: '/login/',
method: 'post',
data: {
'username': $('#id_username').val(),
'password': $('#id_password').val(),
'valid_code': $('#valid_code').val(),
'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
},
success: function (data) {
console.log(data.url)
if (data.code === 100) {
swal({
title: data.msg,
text: '正在为您跳转页面',
type: "success",
timer: 1500,
showConfirmButton: false,
})
setTimeout(function () {
location.href = data.url
}, 1500)
} else if (data.code === 101) {
$('#tips').removeClass('invisible')
$("#tips1").text(data.msg).removeClass('d-none')
$('#id_username').removeClass('is-valid').addClass('is-invalid')
$('#id_password').removeClass('is-valid').addClass('is-invalid')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#id_username').removeClass('is-invalid').val('')
$('#id_password').removeClass('is-invalid').val('')
}, 1500)
} else if (data.code === 102) {
$('#tips').removeClass('invisible')
$("#tips3").text(data.msg).removeClass('d-none')
$('#valid_code').addClass('is-invalid')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#valid_code').removeClass('is-invalid').removeClass('is-valid').val('')
}, 1500)
}
}
})
})
$('#id_username').blur(function () {
$('#id_username').addClass('is-valid')
if ($('#id_username').val().length === 0) {
$('#id_username').removeClass('is-valid').addClass('is-invalid')
$('#tips').removeClass('invisible')
$("#tips1").text('请输入用户名').removeClass('d-none')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#id_username').removeClass('is-invalid').val('')
}, 1500)
}
})
$('#id_password').blur(function () {
$('#id_password').addClass('is-valid')
if ($('#id_password').val().length === 0) {
$('#id_password').removeClass('is-valid').addClass('is-invalid')
$('#tips').removeClass('invisible')
$("#tips2").text('请输入密码').removeClass('d-none')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#id_password').removeClass('is-invalid').val('')
}, 1500)
}
})
$('#valid_code').blur(function () {
if ($('#valid_code').val().length === 0) {
$('#valid_code').addClass('is-invalid')
$('#tips').removeClass('invisible')
$("#tips3").text('请输入验证码').removeClass('d-none')
setTimeout(function () {
$('#tips').addClass('invisible')
$('#valid_code').removeClass('is-invalid').val('')
}, 1500)
}
})
</script>
</body>
</html>