Mark's blog

Content



该系列文章源码来自: 博主第一次手撸博客(Django)
温馨提示: 该系列教程不提供前端布局和美化方面的内容, 博主本行是后端, 在我的项目中前端部分采用的框架是 Materialize, 是谷歌 Material Design 设计风格的前端框架, 欲知详情请点击上方提供的仓库地址, 源码采用WTFPL许可证开源


整体概述

  • 使用 Ajax后端API开发模式
  • 前端有js验证表单(判空)和回车键触发点击事件

开发环境

  • 操作系统: Manjaro Linux 18
  • Python版本: Python3

    提示: Manjaro把Python3作为默认的Python版本, 其他发行版可能默认版本是Python2, 如果默认为Python2, 以下出现的Python和pip命令请使用python3和pip3

  • Django版本: v2.1.5
  • jQuery版本: v3.3.1

HTML部分

1
2
3
4
5
6
7
8
9
10
<form class="col s-12" id="login-form">
<input type="text" id="username" maxlength="8" required onchange="isEmpty()">
<label for="username">用户名</label>

<input type="password" id="password" maxlength="16" required onchange="isEmpty()">
<label for="password">密码</label>

<button type="button" id="login-button" disabled>登录</button>
<button type="reset" disabled>重置</button>
</form>
  • disabled 是禁用的意思, 如果用在按钮上, 这个按钮可能会变灰而且肯定会点下去无效的, 我们默认禁用按钮, 防止有人恶趣味(#手动滑稽)

onchang="isEmpty()" 为表单判空函数


js部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function isEmpty() {
if ($('#username').val() !== "" && $('#password').val() !== "") {
$('#login-button').removeAttr('disabled');
$('#reset-button').removeAttr('disabled');
}
else {
// alert('不输入全就想登录? Naive!');
$('#login-button').attr({"disabled":"disabled"});
$('#reset-button').attr({"disabled":"disabled"});
}
}
document.getElementById('login-button').onclick = function () {
$.ajax({
type: "POST",
url: "/login_api/",
data: {
username: $("#username").val(),
password: $("#password").val()
},
dataType: "json",
success: function (data) {
if (data.status === '1') {
alert('登录成功');
window.location.href=document.referrer||host + "";
}
else if (data.status === '0') {
alert('很显然你正在做一些不该做的事情')
}
},
error: function (jpXHR) {
alert("Status Code: " + jpXHR.status);
},
});
};
document.getElementById('password').onkeydown = function (e) {
// 兼容FF和IE和Opera
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code === 13) {
document.getElementById('login-button').click(); //具体处理函数
return false;
}
return true;
};

详细解析请看前几篇文章: Ajax篇, 表单js判空篇, 回车触发点击篇


views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import login, authenticate

# Login Api
@csrf_exempt
def login_api(request):
if request.is_ajax():
if request.method == "POST":
name = request.POST['username']
pwd = request.POST['password']
user = authenticate(username=name, password=pwd)
if user is not None and user.is_active:
login(request, user)
return JsonResponse({
"status": '1',
"message": '登录成功'
})
else:
return JsonResponse({
"status": '0',
"message": '登录失败'
})
else:
return HttpResponseForbidden()
else:
return HttpResponseServerError()

逻辑结构说明请看上一篇文章: 后端API编写规范篇, 接下来我们解释一下核心的业务逻辑部分

由于这个博客项目的v0.9.0版本并没有打算开放注册功能, 所以不需要在头部引入Django自带的User模型, 我们只需要引入 authenticate 验证模块和 login 登录模块, 接下来只需要讲一下思路, 大家就能明白了. (关于测试, 我们在准备篇-创建超级用户已经创建好了一个用户, 所以可以随意测试)

  • 拆分请求数据
  • 使用 authenticate 方法验证, 如果确实有此用户, 返回一个相应的 User对象, 如果没有, 返回 None
  • 判断, 如果 user变量 不为空且此用户对象是已激活的, 登录并返回给前端一个表示登录成功的Json数据, 如果不满足以上条件, 返回给前端一个表示登录失败的Json数据

有人可能问了, views.py 不是放置视图函数的地方吗? 你这个API函数也不渲染页面, 能叫视图函数吗? 您好, 可以的. 渲染页面只是一部分, 本质是前后端的数据来往.


urls.py

  • 不做描述, 你我都明白.

It’s simple and easy

 评论