Django--分页、session
分页
分页的实现,是由我们自己写的后端代码组建而成,这段写的代码可以直接放在以后的任何分页结构中使用。
先来谈谈原始逻辑:
主页代码如下:
<!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, maximum-scale=1, user-scalable=no">
<title>Title</title>
<link rel="stylesheet" href="/static/dist/css/bootstrap.min.css">
<script src="/static/dist/js/bootstrap.min.js"></script>
<script src="/static/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
<h5>欢迎登录:<span>{{ user }}</span></h5>
<table class="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
</tr>
</thead>
<tbody> {% for item in list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
{% endfor %} </tbody> </table>
<div style="text-align: center">
<ul class="pagination">
{% for item in page_fen %}
{{ item|safe }}
{% endfor %} </ul>
</div>
</div>
</body>
</html>
分页伪数据主页
用模板语言,在后端通过for循环伪造了302条数据,在前端渲染出来。
我们拿到了302条数据之后,首先要想的,是这些数据该分成多少页?由此,便有了一下推想。
首先,我们要想在前端的数据中,我们是怎么区分用户选择的页码的?所以,我们要用到的方法就是GET,通过GET中拼接的url取到?后面的我们所赋予的数值,这样就可以判断用户要浏览的数据页面是
多少页。
d_page=int(request.GET.get("name",1))
取到GET拼接的url值
这样就是我们要取到的页码的值。
接下来我们要设想的,就是每一页中,我们要存放多少条数据?因为只有判断出了每一页存放数据的上限,我们才好将数据进行分页显示。
put_page=10
start=(d_page-1)*put_page
end=(d_page)*put_page
lip = li[start:end]
存放数据上限
代码中,put_page的含义是我们在每一页要存放的数据量,在这里我设定的数据量是10.
下面数据是从数据中的什么地方开始计算的十条数据?我们就要用到python中的切片,起始的数据值和结束的数据值就是通过我们在之前从GET中所去到的当前页码来计算的。
例如我一共伪造了302条数据,我要去到第一页的十条数据,那么我的数据索引就是[0,10],第二页就是[10,20]有了数字就好计算了。
我们取第一页得到的页码自然就是1那么,我们的数据索引就可以看成是
[1-1*put_page,1*put_page]
因为我们设定的数据量是10,所以得到的数据刚好是[0,10]符合我们的要求,再实验第二页的数据
[2-1*put_page,2*put_page] 结果我们发现,得到的数据又恰巧符合我们的结果,所以我们的start和end就可以按照这个方法来取值了,这样,我们就实现了截取每一页要显示的数据的功能
每一页显示的数据量做好了,接下来该思考的,就是怎么编排页码的问题了。
通过bootstrap我们可以直接得到分页div的模型,那么我们怎么判断我们该有多少页码?怎么实现页码与网页的对应呢?
基于这个需求,我编译了以下代码:
page_xi = 11
all_c = len(li)
all_page, tem = divmod(all_c, put_page)
if tem:
all_page += 1
pa_half=int((page_xi-1)/2)
if d_page<=pa_half:
pager_start=1
pager_end = page_xi
elif d_page>=all_page-pa_half:
pager_start = all_page-page_xi
pager_end = all_page
else:
pager_start=d_page-pa_half
pager_end=d_page+pa_half
page_fen=[]
first='<li><a href="%s?name=1">首页</a></li>' % (request.path_info)
page_fen.append(first)
if d_page>1:
prev = '<li><a href="%s?name=%s">上一页</a></li>' % (request.path_info,d_page-1)
page_fen.append(prev)
for i in range(pager_start, pager_end+1):
if i == d_page:
temp = '<li class="active"><a href="%s?name=%s">%s</a></li>' % (request.path_info, i, i,)
else:
temp = '<li><a href="%s?name=%s">%s</a></li>' % (request.path_info, i, i,)
page_fen.append(temp)
if d_page<all_page:
prev = '<li><a href="%s?name=%s">下一页</a></li>' % (request.path_info, d_page + 1)
page_fen.append(prev)
last = '<li><a href="%s?name=%s">尾页</a></li>' % (request.path_info,all_page)
page_fen.append(last)
return render(request,"class.html",{"list":lip,"page_fen":page_fen,"user":user})
实现分页
其中page_xi的含义就是我在每一页要显示的页码中,规定成了11个,然后我们又通过len()方法,获取了数据的总长度,这样我们先通过总数据用divmod的方法,与put_page进行计算,的出来的就是
余数与商,我们这时候就可以判断,如果有余数的话,那么我们就要多给这条数据余出来一页来显示数据,如果没有那么商就是我们需要的总页码。
这个时候,我们使用循环来将标签append进列表,再由模板语言循环渲染的话,就可以的出来所有的页码。
但是,我们之前设定了page_xi来限制页码的数量还没有用到,那么它是做什么的呢?别着急,他当然有大的作用。
数据少的话,我们倒不会觉得有什么问题,但是数据量一多,我们甚至会有几百个页码,那么,我们难道要让他一个贴一个的拍下来嘛?这时候page_xi就要发挥它的作用了,我们是利用他来限制每页所要
显示的页码数量的。
我们通过它减去1除以2也就是代码中的:pa_half=int((page_xi-1)/2)就可以得到pa_half,那么问题来了,pa_half又是做什么用的呢?让我们来一步一步的分析。
假设我们让所已经选择的页码处在这一条页码的最中央,那么前面的一堆页码和后面的一堆页码,加上我所选择的页码加起来就要在我所限定的page_xi以内,所以我们就要获得在我们选择的页码前要展示的
页码数量,与在选择的页码后要展示的页码数量,所以pa_half就是我们所计算的页码数量,也就是我们限定的11个页码值将所选择的一个除外的前后各5个。
这样我们就可以设定页码条所展示的start值和end值了。
但是,这时候还有一个问题,如果我们选择的是第一页或者是尾页呢?它们的前后并没有各5个页码。
没关系,在这个时候我们要加上判断,也就是判断当前所选择的页码是否大于等于我们所设定这个前后页码长度。如果是小于等于的话,那么这个页码值肯定是在5页以内,我们就而已直接用1~11的页码值来表示。
如果这个页码值大于(我们所有页码值减去我们所设定这个前后页码长度)那么它肯定是在最后5页,那么我们直接将end值设为最后一页,start设定为最后一页减去设定的11就好了。
最后我们利用列表的方式,将创建标签的字符串传给模板语言,然后渲染即可。
当然,这么长的代码,如果我以后很多项目都要用到怎么办?很简单,那么我们就自己写一个类,以后用到的时候自己实例化调用就好了,具体类方法:
#使用方法:
# d_page=int(request.GET.get("name",1))
# obj=Pagation(d_page,10,11,len(li),request.path_info) #分别要传的值(当前页,每一页放多少数据,每一页放多少个跳转按钮,数据的长度,当前的url)
#
# lip = li[obj.start:obj.end] #直接引用strat和end方法获取每一页数据的头和尾
# page_fen=obj.huobiao() #huobiao方法获取底下该出来的跳转分页码
# return render(request, "class.html", {"list": lip, "page_fen": page_fen, "user": user}) class Pagation(object):
def __init__(self, d_page,put_page,page_xi,all_c,r_url):
self.d_page=d_page
self.put_page=put_page
self.page_xi=page_xi
self.all_c=all_c
self.r_url=r_url
@property
def start(self):
start = (self.d_page - 1) * self.put_page
return start
@property
def end(self):
end = (self.d_page) * self.put_page
return end
def huobiao(self):
all_page, tem = divmod(self.all_c, self.put_page)
if tem:
all_page += 1
pa_half = int((self.page_xi - 1) / 2)
if self.d_page <= pa_half:
pager_start = 1
pager_end = self.page_xi
elif self.d_page >= all_page - pa_half:
pager_start = all_page - self.page_xi
pager_end = all_page
else:
pager_start = self.d_page - pa_half
pager_end = self.d_page + pa_half
page_fen = []
first = '<li><a href="%s?name=1">首页</a></li>' % (self.r_url)
page_fen.append(first)
if self.d_page > 1:
prev = '<li><a href="%s?name=%s">上一页</a></li>' % (self.r_url, self.d_page - 1)
page_fen.append(prev)
for i in range(pager_start, pager_end + 1):
if i == self.d_page:
temp = '<li class="active"><a href="%s?name=%s">%s</a></li>' % (self.r_url, i, i,)
else:
temp = '<li><a href="%s?name=%s">%s</a></li>' % (self.r_url, i, i,)
page_fen.append(temp)
if self.d_page < all_page:
prev = '<li><a href="%s?name=%s">下一页</a></li>' % (self.r_url, self.d_page + 1)
page_fen.append(prev)
last = '<li><a href="%s?name=%s">尾页</a></li>' % (self.r_url, all_page)
page_fen.append(last)
return page_fen
分页方法
使用方法见注释。
session
session的使用方法很简单,主要是利用原理。
当我们使用session的时候,在每次登陆成功后,就可以将用户名存入session中。
def login(request):
if request.method=="POST":
usname=request.POST.get("username")
pwd=request.POST.get("password")
if usname=="gaoshengyue"and pwd=="gsy121994":
request.session["username"]=usname
return redirect("/class/")
error_msg="输入错误"
return render(request, "zuoye.html", {"error": error_msg})
return render(request,"zuoye.html")
login
session帮我们做成的流程是:
使用request.session["username"]
生成随机字符串
发给用户,写到用户浏览器的cookie中
自己保留一份: {username:'alex',id:1}
在我们使用session前,有两条命令一定要执行,因为他回在我们的项目数据库中建一个session的表用来存放数据
python manage.py makemigrations
python manage.py migrate
这样我们存入session的就是用户名了
我们在取的时候,直接用request.session.get("username")就可以
注销的时候删除这个session : request.session.delete()
session与cookie做比较的话,session比较安全,因为是生成一个随机字符串,自己这里保存一份,放在用户那里一份,相当于一个身份牌,让客户拿着身份牌来验证,然而cookie的话,会直接存在
用户那里,那样的话信息的安全性大大减少。不过因为cookie不会再自己这里存放数据,所以验证速度快,session的速度要比cookie慢。
注销:
def logout(request):
# 获取当前用户的随机字符串
# 在数据库中将当前数据删除
request.session.delete() # del request.session['username'] return redirect('/login/')
logout
Django--分页、session的更多相关文章
- Cookie Session 和Django分页
cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...
- 【python】-- Django 分页 、cookie、Session、CSRF
Django 分页 .cookie.Session.CSRF 一.分页 分页功能在每个网站都是必要的,下面主要介绍两种分页方式: 1.Django内置分页 from django.shortcuts ...
- Cookie、Session和Django分页
cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...
- django cookie session 自定义分页
cookie cookie的由来 http协议是无状态的,犹如人生若只如初见,每次都是初次.由此我们需要cookie来保持状态,保持客户端和服务端的数据通信. 什么是cookie Cookie具体指的 ...
- 6月25日 Django 分页 cookie、session
cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...
- django 分页(2) 使用类 页码显示
django 分页显示页码 views.py 显示11页码 ) < 起始位置 - 10总页数 else 总页数 > IF 当前页 小于 起始位置 结束页 IF 当前页 大于 IF 如果结束 ...
- Django 分页功能
Django 分页功能比较强大,这边是结合官网的内容写的可以参考 https://docs.djangoproject.com/en/1.9/topics/pagination/ 分页命令行练习案列 ...
- Django之Session
Django -- Seeion介绍 问: Django的session是什么? 答: Django 完全支持匿名 Session的. Session 框架允许每一个用户保存 ...
- 浅析Django之session与cookie
浅析Django之session与cookie 1 session与cookie概述 原理: 由于HTTP协议是无状态,无连接的,当用户发起网路请求时,需要服务端能标识用户ID,用以存储用户相关信息, ...
- 原生的 django 分页
原始的 django 分页 # 基本 写法 class Paginator(object): def __init__(self, object_list, per_page, orphans=0, ...
随机推荐
- CodeForces 605 E. Intergalaxy Trips
E. Intergalaxy Trips time limit per test:2 seconds memory limit per test:256 megabytes input:standar ...
- [LeetCode] Factorial Trailing Zeroes 阶乘末尾0
Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in log ...
- 解决mariadb数据库服务无法开启
我的系统Manjaro linux,安装的数据库为mariadb 10.1 1.安装数据库 pacman -S mariadb 2.配置数据库启动环境: mysql_install_db --user ...
- 無法使用 adb push file,Read-only file system
adb root adb remount adb push xxx /system/etc/xxx failed to copy 'xxx' to '/system/etc/xxx': couldn' ...
- 倒计时器CountDownLatch与同步屏障CyclicBarrier
CountDownLatch CountDownLatch是一个非常实用的多线程控制工具类,这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行.在这里指CountDownL ...
- centos7下配置时间同步服务器
同网段20几台服务器: 其中有一组mysql 集群中 互为主从 选一台mysql master 作为时间同步的服务器,这样做的好处以便于这台down了 另一个与他互为主从的master 继续提供时间同 ...
- Codeforces Round #450 (Div. 2) C. Remove Extra One【*模拟链表/一个数比前面所有数大就是个record。删掉一个数,让record的个数尽量多。】
C. Remove Extra One time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Go语言调度器之主动调度(20)
本文是<Go语言调度器源代码情景分析>系列的第20篇,也是第五章<主动调度>的第1小节. Goroutine的主动调度是指当前正在运行的goroutine通过直接调用runti ...
- Codeforces 323C Two permutations
题目描述 You are given two permutations pp and qq , consisting of nn elements, and mm queries of the for ...
- https的实现原理
加密算法 有两种基本的加解密算法类型: 1)对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES.AES等: 2)非对称加密:密钥成对出现(且根据公钥无法推知私钥, ...