【050】Python全栈日记-Django(四)

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

一、Cookie

1、Cookie的认识

基于 Internet的各种服务系统应运而生,建立商业站点或者功能比较完善的个人站点,常常需要记录访问者的一些信息;论坛作为 Internet发展的产物之一,在 Internet 中发挥着越来越重要的作用,是用户获取、交流、传递信息的主要场所之一,论坛常常也需要记录访问者的一些基本信息(如身份识别号码、密码、用户在 Web 站点购物的方式或用户访问该站点的次数)。目前公认的是,通过 Cookie 技术来实现记录访问者的一些基本信息。

 

Cookie 技术诞生以来,它就成了广大网络用户和 Web 开发人员争论的一个焦点。有一些网络用户,甚至包括一些资深的 Web 专家也对它的产生和推广感到不满,这并不是因为 Cookie 技术的功能太弱或其他技术性能上的原因,而是因为 Cookie 的使用对网络用户的隐私构成了危害。因为 Cookie 是由 Web 服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息 。

 

Cookie 可以翻译为“小甜品,小饼干” ,Cookie 在网络系统中几乎无处不在,当我们浏览以前访问过的网站时,网页中可能会出现 :你好 XXX,这会让我们感觉很亲切,就好像吃了一个小甜品一样。这其实是通过访问主机中的一个文件来实现的,这个文件就是 Cookie。在 Internet 中,Cookie 实际上是指小量信息,是由 Web 服务器创建的,将信息存储在用户计算机上的文件。一般网络用户习惯用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 Session 跟踪而存储在用户本地终端上的数据,而这些数据通常会经过加密处理

 

Cookie 在计算机中是个存储在浏览器目录中的文本文件,当浏览器运行时,存储在 RAM 中发挥作用 (此种 Cookies 称作 Session Cookies),一旦用户从该网站或服务器退出,Cookie 可存储在用户本地的硬盘上 (此种 Cookies 称作 Persistent Cookies) [3]  。

通常情况下,当用户结束浏览器会话时,系统将终止所有的 Cookie。当 Web 服务器创建了Cookies 后,只要在其有效期内,当用户访问同一个 Web 服务器时,浏览器首先要检查本地的Cookies,并将其原样发送给 Web 服务器。这种状态信息称作“Persistent Client State HTTP Cookie” ,简称为 Cookies  。

所以总结一下就是cookie相当于识别用户的一个工具,当我们今天登陆过qq空间后,再次登陆就不需要输入密码,也能直接登陆。

 

 

例如昨天我们做的例子:账号密码输入正确后会跳转到主页,但是我们直接通过网址访问主页也是能进去的,再实现用户认证的同时cookie也能实现防止用户跳过登陆页直接访问我们的内容。

 

 

2、初步认识cookie

http请求实际是无状态、用户向服务器发起请求,服务器下发cookie到本地,下次请求,用户携带cookie进行请求,所以短时间访问就不用再次输入密码,因为会直接访问本地的cookie

 

所以有如下几步

[1]我们输入账号密码,点击提交(登陆,注册……)

[2]服务器会对用户进行验证,并把用户的信息作为cookie存放在本地

[3]我们再次访问该服务器时,获取cookie,进行验证。

 

所以:

Cookie解决用户身份问题。

但是cookie不安全,毕竟存放在本地。所以衍生了Session为了解决cookie的安全问题。

 

3、抓包查看cookie

首先要学会如何利用网页抓包,抓包抓的好以后干坏事才轻车熟路。

例如我们研究研究qq空间

[1]用隐私模式进入qq空间登陆页面,用隐私模式主要是减少其他包的干扰,按F12,查看Network,

[2]输入用户名密码,进入qq空间后,在network处会显示自己的qq号,点击此包,查看cookie。

 

 

4、Cookie下发

这里要注意,上图中存在本地的cookie并不是上面那个服务器下发的cookie,而是有登陆页下发的cookie

这就好比唐僧西行,

首先收到李世民的通关文牒,拿着这个文牒才能到下一个国家进行访问,假设为女儿国,访问女儿国的时候,女儿国国王会在通关文牒上盖章,然后到下一个国家的时候别人才会相信你从大唐而来,经过女儿国,来到此处。

我们的cookie就是这个通关文牒,由上一页面进行下发,到下一页面进行使用。

 

那再代码中如何实现cookie下发呢?

Cookie通过登陆页面下发,通过返回值返回数据,所以cookie也应该存储在返回值中。

昨天制作的登陆函数中,对账号密码进行了判断、只有账号密码正确的时候才会下发cookie,所以代码也应该放在判断之后:

 

首先把返回值复制给一个参数,返回值本身有个方法叫做,set_cookie,使用这个方法来设置cookie,设置好cookie后再把参数返回。我们以email作为用户名进行登陆的,所以在cookie中存放的键值对为email

我们这里给cookie设置了一个键值对为email的键值对。这些是我们自定义的参数,还有很多cookie提供的参数,如下:

response.set_cookie(‘key’,’value’) :设置cookie
max_age = None,寿命 秒
expires = None, 过期时间,和寿命时候冲突的
path = '/', cookie起作用的路径,整个网站 /student/
domain = None, cookie起作用的域名 www.baidu.com
secure = False, True用https协议传输cookie
httponly = False, 只用http协议传输,通常情况下,js也可以拿到cookie,但是配置httponly为True,就只有http可以拿到

 

如果我们要在cookie中添加多条:

Response.set_cookie(,key,value='',max_age=None,expires=None,path='/',domain=None, secure=False, httponly=False)。

 

 

既然设置好下发cookie,用登录页试试。

第一次请求登录页面 get,进入页面就会发起一次请求,

等提交了表单内容就会发起第二次请求:登录接口 post,下发的cookie中就包含了我输入的邮箱。

 

 

 

5、Cookie 识别

既然已经设置了cookie,那如何在页面进行识别呢?首先要求获取cookie,然后验证,如果cookie中的内容正确,就可以直接访问首页,如果不正确跳转至登录页。

我们在首页中进行尝试。

 

网页所有请求都存在request中,cookie也不例外,所以从request中获取cookie,获取后进行判断,我这里只做了有没有邮箱的判断,工作中会复杂多,不仅需要判断有没有,还需要判断是否正确。

从cookie中获取邮箱键,判断是否有内容,有内容就认为匹配上了,那就跳转至首页,如果没有获取到email内容,返回登录页。这样就实现了不可以直接跳过登录页访问其他页,除非你有正确的cookie。

 

 

6、cookie装饰器

给首页添加识别后突然发现,好像除了登录页,每一页都需要有一个cookie识别,毕竟想要访问内部内容,跳过登陆那是不可能的,所以基本上百分之99的页面都需要加上cookie识别,那如何添加呢?一个一个加?还是通过一个函数然后调用函数添加?

 

不!这都太不python了

 

当初在python阶段学习过一个东西叫做装饰器,装饰器的目的就是实现一些附加功能的,又高级又装逼,所以当然使用装饰器。


回顾一下装饰器
提取共性、给个性的函数添加共性的功能,例如下图,给python_intruce添加装饰器money。

调用python_instruce就是调用money(python_instruce),fun就代表了python_instruce函数。

 

同理,我们把cookie共性的地方做成装饰器代码如下:

然后修改主页,把主页代码中的cookie识别删了,并给主页函数添加装饰器

看着是不是则舒服,代码干净整洁,非常python。

 


 

二、分页

在我们列表界面,如果有1000个数据,这时候就要使用分页功能了,虽然我们使用的模板自带这个功能,但是还是需要学习一下。

首先我们要删除网页中人家自带的分页方法,只需要修改列表页此处的id即可,它是通过id绑定并传入样式的,修改id他就找不到了。

就这个,我给加了一个s。

 

想要有分页,还需要数据,我们通过一个函数,一次写入100个数据。这里使用之前定义的学生表,所以字段一定要对应,首先一个姓列表,一个名列表(百度搜的),数据还有其他字段,然后可以通过random.choice()选取列表中的姓名。然后通过s实例化表,给表中字段赋值,并通过for循环100变,最后页面返回至列表页。

在路由urls中关联这个函数,通过网页调用函数,生成列表。

去数据库看看数据是否生成。

 

数据有了,记住把数据关联在你的学员列表页。这时候页面会有100条数据,特别长。

接下来就要做分页了,我们假设每页显示10个学员。

 

[1]假如有101个数据,每页10个,那应该是11页。

所以用学员数量除以每页个数,如果是整除,那结果就是页数,

如果不能整除,就需要取整,但是比如101除以10取整是10,而我们需要11页,所以如果不能整除,就需要结果加1.

 

[2]我们从数据库中取出所有数据,取出的为一个字典组成的列表,我们每页展示10个,我们取的是列表中的下标,而且在python中取数是左闭右开,所以:

第1页:取0-10,10取不到,10个数据

第2页:取10-20,20取不到,10个数据

第3页:取20-30,30取不到,10个数据

所以:第n页:取(n-1)*10-n*10,10个数据

 

[3]正常情况下,我们在表下会显示页数索引,但是一般只显示当前页前两页和当前页后两页,当页数为1,2,3显示前5页。

 

[4]当页数超过总页数,跳回第一页。

 

 

接下来就是代码实现:

写在视图页面(view)

既然每页数据不同,这就和当初学生详情页一样,需要在一个页面显示多个数据,所以需要使用正则表达式来进行匹配。所以在视图页进行关联的时候path使用正则:

最后需要修改列表页面:

当然可以给按钮加点样式:style="display: inline-block;width: 30px;height: 30px"

 

 

三、Django内置分页方法

参考链接:链接(https://www.cnblogs.com/king-lps/p/7324821.html)

 

首先你要先导入Paginator

from django.core.paginator import Paginator

 

再创建分页对象 ,然后通过这个对象来调用分页的所有的属性

paginator = Paginator(book_list, 2)  #设置每一页显示几条,创建一个panginator对象

 

1、Paginator类属性属性与方法

类方法:

Paginator.page(number):根据参数number返回一个Page对象。(number为1的倍数)

 

类属型:

[1]Paginator.count:

所有页面对象总数,即统计object_list中item数目。当计算object_list所含对象的数量时, Paginator会首先尝试调用object_list.count()。如果object_list没有 count() 方法,Paginator 接着会回退使用len(object_list)。

[2]Pagnator.num_pages:页面总数。

[3]pagiator.page_range:页面范围,从1开始,例如[1,2,3,4]。

 

 

2、Page类的解释

通常不用手动创建Page对象,可以从Paginator.page()来获得他们。

 

类方法

[1]Page.has_next() 

如果有下一页,则返回True。

[2]Page.has_previous()

如果有上一页,返回 True。

[3]Page.has_other_pages()

如果有上一页或下一页,返回True。

[4]Page.next_page_number()

返回下一页的页码。如果下一页不存在,抛出InvlidPage异常。

[5]Page.previous_page_number()

返回上一页的页码。如果上一页不存在,抛出InvalidPage异常。

[6]Page.start_index()

返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3。

[7]Page.end_index()

返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index() 会返回 4。

 

 

类属型

[1]Page.object_list

当前页上所有对象的列表。

[2]Page.number

当前页的序号,从1开始。

[3]Page.paginator

相关的Paginator对象。

 

猜你喜欢

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