url(r'^baobao/$', baobao),
]
from django.shortcuts import render, HttpResponse
def login(request):
return render(request, ‘login.html’)
def baobao(request):
# 获取用户提交的数据,做是否登录成功的判断
email = request.POST
print(request.POST)
return HttpResponse(‘O98K’)
请登录
启动项目,在浏览器输入 http://127.0.0.1:8000/login/,回车,顺利出现了我们的登录页面。
一脸兴奋,输入随便一个邮箱、密码,点击登录。什么?怎么提示错误了!!!
你确定你输入的是邮箱地址吗(*/ω\*)…
这一个提示,是 bootstrap 前端框架帮我们做的,在前端就进行了一次简单的表单验证。boostrap 是什么?你现在姑且把它当成是一个前端框架,我们以后再讲。
初涉 CSRF
再一次,输入正确的邮箱地址,密码,点击登录。Forbidden?这是什么鬼???
可以看到,url 已经成功跳转到 baobao 了,不过页面却显示 Forbidden。下面还有一行 CSRF verification failed. Request aborted. 这一个是 Django 自带的 CSRF 防范机制。CSRF 是什么?某度百科有言:“CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。”(可以看出,我们的 Django 框架,可是相当的严谨和方便。)
那么,这里我们应该怎么做呢?我们只需要在 form 表单标签内部加上一句 {% csrf_token %} 即可。
此时的 login.html 应为
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
<title>mysite-登录页面</title>
<style>
body {
background-color: #eee;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
<h1 class="text-center">请登录</h1>
<form class="form-horizontal" action="/login/" method="post">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label"></label>
<div class="input-group col-sm-8">
<span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span>
<input type="email" name="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label"></label>
<div class="input-group col-sm-8">
<span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
<input type="password" name="pwd" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="input-group col-sm-offset-2 col-sm-8">
<div class="checkbox">
<label>
<input type="checkbox"> 记住我
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="input-group col-sm-offset-2 col-sm-8">
<button type="submit" class="btn btn-primary btn-block">登录</button>
</div>
</div>
{% csrf_token %}
</form>
</div>
</div>
</div>
</body>
</html>
重启项目,再次回到 login 页面,输入,登录。终于看到我们想要的 ‘O98K’ 了。 o(╥﹏╥)o
提取数据及账号密码验证
而且可以在 pycharm 的 Terminal 中看到打印出来的数据。(我是在 pycharm 的 Terminal 中启动项目的,所以可以在这里看到打印的数据)
‘email’ 对应的是我们输入的邮箱。‘pwd’ 对应的是我们输入的密码。‘email’ 和 ‘pwd’ 是在哪里定义的呢?是我们在 login.html 的 form 的 input 中定义的 name 属性。要想给服务器传数据,必须给它们起一个 name。
既然可以获取到浏览器传过来的数据了,我们就可以在 baobao 函数中取出这些数据,做邮箱、密码的验证。
from django.shortcuts import render, HttpResponse
def login(request):
return render(request, 'login.html')
def baobao(request):
# 获取用户提交的数据,做是否登录成功的判断分别
# 取出邮箱和密码进行验证
email = request.POST.get('email', None)
pwd = request.POST.get('pwd', None)
if email == '123@qq.com' and pwd == 'abc123':
# 登录成功
return HttpResponse('登录成功')
else:
# 登录失败
return HttpResponse('登录失败')
输入错误的邮箱和密码进行登录,再输入正确的邮箱和密码进行登录。可以看到,我们想要的逻辑都能够正确运行。
逻辑及 url 优化
整理一下逻辑
首先,启动项目之后,在浏览器输入 http://127.0.0.1:8000/login/,浏览器就会给服务器发送一个 GET 请求,服务器给浏览器返回 login 页面。当用户填完登录表单点击登录的时候,浏览器就会向服务器发送一个 POST 请求,给服务器提交数据。服务器收到浏览器提交过来的数据(邮箱、密码),在逻辑函数中进行验证,并给浏览器返回相应的结果。
到这里,不知道你是否发现,我们的逻辑函数和 url 设置太过累赘。明明是一个登录功能,却写了两个页面,用两个函数进行处理。下面,我们将对代码进行改进。把返回 login 页面和 邮箱密码验证 功能都写进 login 函数中。
from django.shortcuts import render, HttpResponse
def login(request):
if request.method == 'POST':
# 获取用户提交的数据,做是否登录成功的判断分别
# 取出邮箱和密码进行验证
email = request.POST.get('email', None)
pwd = request.POST.get('pwd', None)
if email == '123@qq.com' and pwd == 'abc123':
# 登录成功
return HttpResponse('登录成功')
else:
# 登录失败
return HttpResponse('登录失败')
# 如果不是POST,就返回login页面
return render(request, 'login.html')
相应的,login.html 中 form 的 action 也要改变成 login,urls.py 和 views.py 中的 baobao 相关可以删除。
登录测试,发现可以正常运行,而且 url 一直都是 login。
页面优化
什么?你说这样太丑了???
对,这样的登录功能实在是太丑了,一般的登录失败之后都不会跳转到另一个页面说你登录失败,而是在输入邮箱和密码的页面就提示登录失败了。
好的,那我们就动手改一下吧。要想错误信息显示在登录界面,就是说需要后端返回一个值到前端来。我们在 login 函数里面整理逻辑,在函数一开始的时候,就先给它一个空的错误信息,如果浏览器传过来的是 POST 方法,并且账号密码不正确,那么错误信息 error_msg 就是 ‘账号或密码错误’。然后再通过 render 模块返回浏览器。
from django.shortcuts import render, HttpResponse
def login(request):
error_msg = ''
if request.method == 'POST':
# 获取用户提交的数据,做是否登录成功的判断分别
# 取出邮箱和密码进行验证
email = request.POST.get('email', None)
pwd = request.POST.get('pwd', None)
if email == '123@qq.com' and pwd == 'abc123':
# 登录成功
return HttpResponse('登录成功')
else:
# 登录失败
error_msg = '账号或密码错误'
# 如果不是POST,就返回login页面
return render(request, 'login.html', {'error': error_msg})
同时,login.html 也需要提取后端传过来的 error_msg ,并显示在登录页面上,相应的代码如下。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
<title>mysite-登录页面</title>
<style>
body {
background-color: #eee;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
<h1 class="text-center">请登录</h1>
<form class="form-horizontal" action="/login/" method="post">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label"></label>
<div class="input-group col-sm-8">
<span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span>
<input type="email" name="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label"></label>
<div class="input-group col-sm-8">
<span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
<input type="password" name="pwd" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="input-group col-sm-offset-2 col-sm-8">
<div class="checkbox">
<label>
<input type="checkbox"> 记住我
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="input-group col-sm-offset-2 col-sm-8">
<button type="submit" class="btn btn-primary btn-block">登录</button>
</div>
<p class="text-danger text-center">{{ error }}</p>
</div>
{% csrf_token %}
</form>
</div>
</div>
</div>
</body>
</html>
测试登录功能,一切正常,登陆成功跳转页面并显示“登录成功”,登录失败直接在表单下显示错误信息。
初涉模板语言
你可能会疑惑,刚才我们在 login.html 中加的一句 {{ error }} 是什么意思啊?没见过啊?
文末有福利领取哦~
👉一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
👉二、Python必备开发工具
👉三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
👉 四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
👉五、Python练习题
检查学习结果。
👉六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!