类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | /user/login/ |
参数格式 | 无参数 |
返回结果
登录页面
from django.shortcuts import render
from django.views import View
# ....
class LoginView(View):
"""
登录视图
"""
def get(self, request):
return render(request, 'user/login.html')
from django.urls import path, include
from . import views
app_name = 'user'
urlpatterns = [
path('register/', views.RegisterView.as_view(), name='register'),
path('login/', views.LoginView.as_view(), name='login'),
]
1.user/login.html
因为表单需要post请求,所以记得在页面使用{% csrf_token %}
标签。
注册功能已经开发好了,所以页面的上的立即注册
处的a标签href可以写好
{% extends 'base/base.html' %}
{% load static %}
{% block title %}登录{% endblock title %}
{% block link %}
<link rel="stylesheet" href="{% static 'css/user/auth.css' %}">
{% endblock link %}
{% block main_start %}
<!-- container start -->
<main id="container">
<div class="login-contain">
<div class="top-contain">
<h4 class="please-login">请登录</h4>
<a href="{% url 'user:register' %}" class="register">立即注册 ></a>
</div>
<form action="" method="post" class="form-contain">
{% csrf_token %}
<div class="form-item">
<input type="text" placeholder="请输入用户名或手机号" name="account" class="form-control" autocomplete="off">
</div>
<div class="form-item">
<input type="password" placeholder="请输入密码" name="password" class="form-control">
</div>
<div class="form-item clearfix">
<label>
<input type="checkbox" name="remember">
<span>记住我</span>
</label>
<a href="javascript:void(0);" class="forget-password">忘记密码?</a>
</div>
<div class="form-login">
<input type="submit" value="登录" class="login-btn">
</div>
{% csrf_token %}
</form>
</div>
</main>
<!-- container end -->
{% endblock main_start %}
接口说明:
类目 | 说明 |
---|---|
请求方法 | POST |
url定义 | /user/login/ |
参数格式 | 表单参数 |
参数说明:
参数名 | 类型 | 是否必须 | 描述 |
---|---|---|---|
account | 字符串 | 是 | 用户输入的用户名 |
password | 字符串 | 是 | 用户输入的密码 |
remember | 字符串 | 否 | 用户是否选择免登录 |
返回结果:
{
"errno": "0",
"errmsg": "OK",
}
class LoginView(View):
"""
登录视图
"""
def get(self, request):
return render(request, 'user/login.html')
def post(self, request):
form = LoginForm(data=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)
class LoginForm(forms.Form):
account = forms.CharField(error_messages={'required': '账户不能为空'})
password = forms.CharField(max_length=20, min_length=6,
error_messages={
'max_length': '密码长度要小于20',
'min_length': '密码长度要大于6',
'require': '密码不能为空'
})
remember = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super().__init__(*args, **kwargs)
def clean_account(self):
"""
校验用户账户
:return:account
"""
account = self.cleaned_data.get('account')
if not re.match(r'^1[3-9]\d{9}$', account) and (len(account)<5 or len(account)>20):
raise forms.ValidationError('用户账户格式不正确,请重新输入')
# 一定要return
return account
def clean(self):
"""
校验用户名密码,并实现登录逻辑
:return:
"""
cleaned_data = super().clean()
account = cleaned_data.get('account')
password = cleaned_data.get('password')
remember = cleaned_data.get('remember')
# 登录逻辑
#Q 相当于 or,判断输入账户是是手机号或用户名
user_queryset = User.objects.filter(Q(mobile=account)|Q(username=account))
if user_queryset:
user = user_queryset.first()
#user.check_password()是框架自带的用来校验密码是否一致的方法
if user.check_password(password):
if remember:
self.request.session.set_expiry(constants.USER_SESSION_EXPIRY)
else:
self.request.session.set_expiry(0)
login(self.request, user)
else:
raise forms.ValidationError('用户名密码错误!')
else:
raise forms.ValidationError('用户账号不存在,请重新输入!')
# 用户session信息过期时间 单位秒 默认14天
USER_SESSION_EXPIRY = 14*24*60*60
修改user/login.html中用户账户输入框input的name为account
。
在static/js/user/下创建login.js文件
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
}
}, 3000)
}else{
message.showError(res.errmsg)
}
},
error: function (xhr, msg) {
message.showError('服务器超时,请重试')
}
});
});
});
接口说明:
类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | /user/logou/ |
参数格式 | 无参数 |
2.后端代码
# 在user目录下的views.py文件中定义如下视图:
class LogoutView(View):
"""
登出视图
"""
def get(self, request):
logout(request)
return redirect(reverse('user:login'))
# 在urser目录下的urls.py文件定义如下路由:
from django.urls import path
from . import views
app_name = 'user'
urlpatterns = [
path('register/', views.RegisterView.as_view(), name='register'),
path('login/', views.LoginView.as_view(), name='login'),
path('logout/', views.LogoutView.as_view(), name='logout'),
]
3.前端代码
# 修改templates/base/base.html中的header部分的代码如下
<header id="header">
<div class="mw1200 header-contain clearfix">
<!-- logo start -->
<h1 class="logo">
<a href="javascript:void(0);" class="logo-title">Python</a>
</h1>
<!-- logo end -->
<!-- nav start -->
<nav class="nav">
<ul class="menu">
<li class="active"><a href="base.html">首页</a></li>
<li><a href="../course/course.html">在线课堂</a></li>
<li><a href="../doc/docDownload.html">下载文档</a></li>
<li><a href="search.html">搜索</a></li>
</ul>
</nav>
<!-- nav end -->
<!-- login start -->
<div class="login-box">
{% 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 'user:logout' %}">退出登录</a></li>
</ul>
</div>
{% else %}
<div>
<i class="PyWhich py-user"></i>
<span>
<a href="{% url 'user:login' %}" class="login">登录</a> / <a href="{% url 'user:register' %}"
class="reg">注册</a>
</span>
</div>
{% endif %}
</div>
<!-- login end -->
</div>
</header>