【049】Python全栈日记-Django(三)

版权声明:作者:人学物理死的早 出处:https://blog.csdn.net/weixin_39561473 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 https://blog.csdn.net/weixin_39561473/article/details/86582806

上一个日记学习了如何从数据库中提取数据,今天来学习,如何获取网页上用户提交,用户输入,并将用户输入数据存入服务器中或者进行比对。

总结以下mvc就是这么一幅图,橙色的线路已经学会了,接下来研究红色的那天线路如何实现。

一、Django 请求

用户从网页传递数据的方式通常是将数据写在文本框中,然后通过提交按钮将数据提交,我们获取用户提交数据的方法通常使用:

[1]Form表单

[2]Ajax

[request参数]

我们之前一直都忽略了一个写在视图(view)中的一个参数request,接下来研究一下request参数。

在视图当中,大部分函数有request参数,request这个参数是当URL(统一标识符,就是网址)调用视图函数的时候接收传递的请求。所以Request接收的就是一个请求。

通过Request.META方法能查看请求当中携带的参数:

一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:

CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。

CONTENT_TYPE —— 请求的正文的MIME 类型。

HTTP_ACCEPT —— 响应可接收的Content-Type。

HTTP_ACCEPT_ENCODING —— 响应可接收的编码。

HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。

HTTP_HOST —— 客服端发送的HTTP Host 头部。

HTTP_REFERER —— Referring 页面。

HTTP_USER_AGENT —— 客户端的user-agent 字符串。

QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。

REMOTE_ADDR —— 客户端的IP 地址。

REMOTE_HOST —— 客户端的主机名。

REMOTE_USER —— 服务器认证后的用户。

REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。

SERVER_NAME —— 服务器的主机名。

SERVER_PORT —— 服务器的端口(是一个字符串)

也就是说request这个参数里就包含了我们需要获取的所有网页上的数据,那如何把数据作为请求放入request呢?

就要通过:Form表单、Ajax 、Url get请求

二、Form表单

学前端的时候提到过from有两个参数,

[1]action

[2]method

1、Action 是请求的地址

地址为空,就是请求自己的地址,也就是把本页的数据作为请求。

2、Method 请求的方式

Post 发送,密文的

Get  获取,明文

最直观的区别就是GET把参数包含在URL中,POST通过request 传递参数。

在URL中,我们填写的的数据以?开始,以键=值的形式以&分割,

例如百度搜索,我们完全可以通过在网址栏通过修改wd=的值达到搜索的效果:

3、input

From表单中我们使用input来添加文本框、密码框、提交框等等,input有个属性为name,name就是传递参数的键,也就是百度的那个wd

4、Submit

在input中有个特殊的类型叫做submit,submit中文意思为提交,也就是把所有填写在from表单中的数据都提交,提交的是from属性中action所写地址的请求,使用method所写的方法

三、练习:

今天还是使用上回提供的模板(https://codeload.github.com/BlackrockDigital/startbootstrap-sb-admin/zip/gh-pages

今天使用注册页在昨天的school项目中继续补全

先把注册页复制进template,然后修改css、js的路径,如果有照片还需要修改照片的路径。

由于模板没有给input添加name属性,所以添加name属性,

再给from标签添加属性action和method,method使用post

并修改注册键位input的submit键,原文件使用的是a标签。

而且修改一下,更符合自己使用,比如删除lastname,比如修改显示文字为中文。

然后关联网页至视图和路由:

查看一下页面

然后我们按照要求输入、就会报一个错误CRSF验证失败,

四、CRSF

CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

很久以前盗qq就是这么做到的,所以之后所有的web后端制作都会默认添加对csrf的防御,这也就是为什么会发生上面的报错,我们需要给网页添加csrf防御

Django为了防止csrf攻击,再设置setting里定义csrf中间件,我们需要的就是在网页中添加这个中间件。

所以,所有的post请求多应该在form表单下的第一行添加csrf_token标签

最后假如我们的视图函数需要接收添加csdn防御的post请求,那么,我们的加载模块必须是render,Render 和其他方法唯一的不同就是第一个参数需要是request

这样再点提交就不会报错了,就可以完成数据的提交了。

五、视图接收数据并存入数据库

1、视图接收数据

我们已经可以做到将填入的数据进行提交,那如何获取这些数据,并存放入数据库呢?

之前说了提交的说有请求都会存放在视图的request参数中。取这些数据自然是从request中提取。

我们常用的提取request数据的方法有:

[1]request.method

返回请求的方式,此方法的返回值有: POST和GET
[2]request.POST

接收所有POST过来的数据
[3]request.GET 

接收所有GET过来的数据

首先我们要进行判断,是否收到了表单提交了数据,如果提交了请求那所用方式应该为post,这是我们在from属性中设置的。

如果有数据就对数据进行获取,所有提交的数据都是以键值对的方式存放的,所以取出也是通过键来取,键就是input中的name属性所填写的内容,而值就是填写在name对应的input框中的内容。

确认密码不需要咱们来判断,前端在js中就会进行判断,所以不需要获取确认密码。这些需要写在注册页面函数下:

2、数据存入数据库

既然获取到了数据,那我们就需要把注册的用户存在数据库中,让他们们可以进行登陆访问所以需要在数据库中创建一张用户用户表,用来存放注册的用户。

[1]建模

建模的字段应该与从注册页获取的一致

[2]然后虚拟环境下同步数据库

[3]最后视图中通过字段接收内容存入数据库

首先在视图导入models中的userinfo表

然后改写注册页面的函数

[4]这样注册页就写完了,登陆网址,去注册一个,这样就可以在数据库中查看自己注册的数据了。

Pycharm给我们提供了完整的生产环境,当然包括数据库,在pycharm中打开数据库

然后点击userinfo表,就能看到刚才在注册页面写入的数据了。

这样数据写入就完成了,让我们研究一下其中的过程:

但是这里有个逻辑问题,如果我们注册成功,获取到前端传来的数据,应该跳转到登陆页面

而我们写的并不会跳转,只是原地打转,注册完了还是显示注册页面。

跳转很简单,只需要修改返回语句就可,首先导入模块:

from django.shortcuts import HttpResponseRedirect

然后修改返回语句,我们是在成功注册的时候才会跳转,所以修改视图中if内的那个返回语句,按照逻辑应该是跳转至登录页,所以做如下修改:

[1]把sb-admin模板中的登录页拉进来,我们后面会做登录页的逻辑的。

在视图界面写登陆界面函数、在路由中绑定

[2]修改视图中注册页返回属性

再次尝试注册,注册成功就可以进行跳转。

From表单提交就讲到这里,接下来是Ajax

六、Ajax请求

在我们使用from表单进行请求的时候会携带整个页面的所有数据提交提交,并且会页面刷新或者跳转,可是很多网站都有一个功能,在你注册的时候,当你输入的邮箱在服务器中存在的时候,就会提醒你该邮箱已被占用,请重新输入。

这说明,在你填写完邮箱后,发生了一个关于邮箱验证的请求,这种局部发起的请求就是Ajax请求,Ajax请求可以极大提升用户体验,因为你用from请求提交后你的填写的数据都没了,你还得再次填写所有数据。

所以Ajax的特点:

[1]局部提交

[2]不影响其他体验

Ajax技术是一个基于JavaScript的前端技术,运作原理如下

首先在使用Ajax之前,要确认数据库已经存在

1、先编写前端的ajax代码

在注册页html中:

我们提醒用户可以通过alert弹窗的方式,但是这样真的很low,用户体验也不好,所以我们选择使用标签,进行隐藏和显示,我们将标签写在输入邮箱邮箱的标签中:

标签的css样式如下:

style="display:none; position:absolute; left:477px; top:10px; background-color:red; color:white; width:110px; height: 30px; border-radius: 6px; text-align: center; line-height: 30px; font-size:14px "

标签本身是隐藏的,只有邮箱重复时才会显示。

我们在什么情况下会触发ajax呢?当然是输入完邮箱后,鼠标移出输入框后触发,也就是离焦时间发生时,触发Ajax。所以先在注册页面写jQuery代码:

最简单的ajax样式。

我们通过Ajax返回给视图request请求中的数据是我们输入在邮箱框中的内容,所以先提取输入框中内容,这样一个ajax结构就完成了:

在请求成功中应该进行判断:

[1]如果库中存在此邮箱,之前设置的标签就会显示,告诉用户邮箱已经存在。

[2]如果库中不存在邮箱,标签隐藏。

我给标签起的id为alterf

url是我们使用的是url get的方法,也就是从网址中获取数据,get方法数据会以?key=value& key=value& key=value的方式存在网址中。

然后我们编写了ajax的响应视图,在最开始说ajax的时候,我们通过ajax发送请求,然后通过json把数据传入ajax。

所以在视图(view)中

[1]先导入json模块

from django.http import JsonResponse

[2]因为ajax中设置的是通过get方法发起请求,所以视图中先判断是否传入get请求而且是否get到数据。

[3]从url get中获取email,进行匹配,如果数据库中有用户使用了该email,则返回结果为一个字典,否则也返回一个结果的字典,因为ajax中的data接收数据必须使用字典格式。

在路由中进行关联:

既然关联了路由,那就可以进行验证了,因为get请求是获取url(网址)的,网址中请求以键值对存放,所以我们可以通过/emailCheck/?email=xxxx来验证视图中的函数是否生效:

由上图可知,逻辑没有错误,这时候就可以把此url写在ajax当中,并对返回值进行判断。

效果如下:

七、密码加密

查看一下我们的数据库:

密码直接裸露在外面是不是看着非常的难受,这样用户的信息是非常不安全的,这时候就需要对密码进行加密,通常使用md5算法进行哈希加密。

1、哈希加密与md5算法

哈希(Hash)是将目标文本转换成具有相同长度的、不可逆的杂凑字符串(或叫做消息摘要)

Md5是一种使用哈希的加密算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

重点就是:相同长度、不可逆

例如:

给1进行md5加密是:c4ca4238a0b923820dcc509a6f75849b

给2进行md5加密是:c81e728d9d4c2f636f067f89cc14862c

给12进行md5加密为:c20ad4d76fe97759aa27a0c99bff6710

给12345678加密为:25d55ad283aa400af464c76d713c07ad

因为长度相同,不存在任何规律,所以基本不可破解,但是也可以通过字典进行挨个尝试,在大量的时间积累下也可以破解。

所以,一些大的公司会对密码进行2次甚至3次的加密,这样基本不存在破解的可能了。

2、注册时给密码进行加密

[1]导入哈希模块

[2]编写md5加密函数

[3]给输入密码的变量添加加密函数

函数背下即可:

使用加密函数:

再次注册一个用户,查看数据库:

八、登陆界面

注册界面有了,那如何使用注册的账户登陆首页呢?

1、在做注册完成跳转的时候已经在项目中导入了注册页,首先修改注册页面的样式(css,js)

2、因为使用from表单进行提交,所以需要修改登陆按钮为submit和修改from的属性。

3、设置视图和路由,在注册跳转的时候已经做过了。

4、登陆的判断逻辑

[1]判断是否通过post方式获取请求且有请求内容

[2]获取用户输入的账号密码,判断邮箱是否在数据库中存在,也就是是否注册过,如果没有跳转至注册页

通过命令:UserInfo.objects.filter(email=inemail)从数据库中取出该用户的说有数据,使用filter取数据,格式为[{数据}],是字典嵌套在列表中,所以需要通过.firsth或者[0]来取出字典。

[3]如果邮箱验证通过后

判断输入的密码是否为该用户对应的密码,别忘记给用户输入的密码加密,库里的密码是加密的。

如果密码正确,跳转至首页。

如果密码错误,提醒用户密码错误。

所以是个if嵌套结构:

然后修改登陆的页面,接收参数和定义三秒后跳转:

这样功能就是实现了:

登陆成功跳转至首页,首页我们并没有添加,所以从sb-admin模板中导入html,进行样式、视图和路由的修改,顺便将之前做的学生表单和学生详情页进行关联,做成一个完整的网站。

在下次的日记中将会使用到跳转来实现cookie。

猜你喜欢

转载自blog.csdn.net/weixin_39561473/article/details/86582806
今日推荐