Django分页器和自定义分页器
一.自定义分页器
import copy class Pagination():
def __init__(self,request,current_page,all_data_num,each_page_data_num=10,max_page_num=11):
#封装页面相关数据
'''
current_page:当前页
data_num:数据总条数
each_page:每页数据条数
max_page_num:最大显示的页码数
page_num: 总页数
'''
self.url_data= copy.deepcopy(request.GET)
# page =1&a=1&b=2 try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page <1:
current_page = 1 self.current_page =current_page
self.all_data_num = all_data_num #
self.each_page_data_num =each_page_data_num #
self.max_page_num = max_page_num #总大显示的页码数
# 计算总页数
total_page_num,tmp = divmod(self.all_data_num,self.each_page_data_num)
if tmp:
total_page_num +=1
self.total_page_num = total_page_num #总页数 self.page_count_half = int((self.max_page_num-1)/2) @property
def start(self):
return (self.current_page-1)*self.each_page_data_num @property
def end(self):
return self.current_page*self.each_page_data_num def page_html(self):
#总页码 < 最大显示的页码数
if self.total_page_num <self.max_page_num:
page_start = 1
page_end =self.total_page_num+1 #总页码 > 最大显示的页码数
else: if self.current_page <=self.page_count_half:
page_start = 1
page_end =self.max_page_num+1
elif (self.current_page+self.page_count_half)>self.total_page_num:
page_start=self.total_page_num-self.max_page_num+1
page_end =self.total_page_num+1
else:
page_start =self.current_page-self.page_count_half
page_end =self.current_page+self.page_count_half+1 page_html_lst=[] #首页,上一页标签
self.url_data["page"]=1
frist_page ='<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?%s">首页</a></li>'%(self.url_data.urlencode(),)
page_html_lst.append(frist_page)
self.url_data["page"] = self.current_page-1
if self.current_page<=1:
prev_page ='<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?%s">上一页</a></li>'%(self.url_data.urlencode(),)
page_html_lst.append(prev_page) #每页显示的页码 for i in range(page_start,page_end):
self.url_data["page"] = i
if i == self.current_page:
tmp ='<li class="active"><a href="?%s">%s</a></li>' % (self.url_data.urlencode(), i,)
else:
tmp ='<li><a href="?%s">%s</a></li>' % (self.url_data.urlencode(), i,)
page_html_lst.append(tmp) self.url_data["page"] = self.current_page + 1
if self.current_page >=self.total_page_num:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?%s">下一页</a></li>' % (self.url_data.urlencode(),)
page_html_lst.append(next_page)
self.url_data["page"] =self.total_page_num
last_page = '<li><a href="?%s">尾页</a></li></ul></nav>' % (self.url_data.urlencode(),)
page_html_lst.append(last_page) return "".join(page_html_lst)
自定义分页器的使用:
该分页器依赖:bootstrapt 的样式
pagination = Pagination(参数)
1. 最关键的两个参数:
1.当前页的页码 当前页码 reuqest.GET.get("page")
2.以及需要分页的数据条数
2. 该分页器 能做的:
1. 将数据分好页,且 通过该类的两个属性 ,可以得到当前页的数据范围 总数据进行切片 [pagination.start: pagination.end],得到当前页的数据,可以通过循环展示的页面。
2. pagination.page_html() 该方法,实现页码展示效果
保存搜索路径
1. 浏览器请求: http://127.0.0.1:8020/yema/?page=4&a=1&b=2&q=3
2.后端涉及到的知识点:
param = copy.deepcopy(request.GET) # 此字典可以变 ,通过 param["page"] = 值 改变 page 的页码
param.urlencode() # 把字典类型的数据转化成 此种格式的 数据 :page=4&a=1&b=2&q=3
后端实现逻辑:自定义分页器
from django.utils.safestring import mark_safe
import copy
class Pagination(object): def __init__(self,request,current_page,data_num,per_page_data_num,show_page_num): try:
self.current_page = int(current_page)
except Exception as e: #当前页码
self.current_page = 1
self.data_num = data_num # 数据总条数
self.per_page_data_num = per_page_data_num #没页显示的数据条数
self.show_page_num = show_page_num # 显示的页码条数
self.request = request #计算总页数 page_nums
num,b = divmod(self.data_num,self.per_page_data_num) if b:
self.page_nums = num+1
else:
self.page_nums = num self.half_range = int((self.show_page_num-1)/2) @property
def start(self):
start = (self.current_page-1)*self.per_page_data_num
return start @property
def end(self):
end = self.current_page*self.per_page_data_num
return end @property
def page_range(self):
# 显示的页面数 show_page_num 11 #如果总页码数小于 show_page_num
if self.page_nums<=self.show_page_num:
page_range = range(1,self.page_nums+1)
else: # 如果页面数大于show_page_num
#如果当前页码数 +half 小于 show_page_num,就显示前show_page_num
if (self.current_page+self.half_range)<= self.show_page_num:
page_range = range(1,self.show_page_num+1) #如果当前页+half 大于 page_nums ,就显示最后show_page_num
elif (self.current_page+self.half_range)>= self.page_nums:
page_range = range(1,self.page_nums+1)[-self.show_page_num:] else:
page_range = range(self.current_page-self.half_range,self.current_page+self.half_range) return page_range #页码的实现
def page_html(self):
param = copy.deepcopy(self.request.GET)
#首页
param["page"] = 1
first_page= '<nav aria-label="Page navigation"><ul class="pagination"><li>' \
'<a href="?%s"><span aria-hidden="true">首页</span> </a></li>'%param.urlencode()
#上一页
param["page"] = self.current_page-1
if self.current_page-1>0:
per_page = '<li><a href="?%s">'\
'<span aria-hidden="true">上一页</span> </a></li>'%(param.urlencode())
else:
per_page = '<li><span aria-hidden="true" class="disabled">上一页</span></li>' page_body = '' #中间页 for num in self.page_range:
param["page"] = num
if self.current_page == num: page_h ='<li class ="active"><a href="?%s" >%s</a></li>'%(param.urlencode(),num) else:
page_h = '<li> <a href="?%s">%s</a> </li>' % (param.urlencode(), num) page_body+= page_h #下一页
param["page"]=self.current_page+1
if self.current_page<self.page_nums:
next_page = '<li><a href="?%s" aria-label="Next">'\
'<span aria-hidden="true">下一页</span></a></li>'%(param.urlencode()) else:
next_page = '<li><span aria-hidden="true" class="disabled">下一页</span>' #尾页
param["page"] = self.page_nums
last_page = '<li><a href="?%s"><span aria-hidden="true">尾页</span></a></li></ul></nav></li>'% param.urlencode()
page_html = first_page+per_page + page_body + next_page+last_page return mark_safe(page_html)
二. Django 分页器的使用
1.批量创建数据
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
批量创建数据
book_list=[]
for i in range(1,101): book=Book(name="book%s"%i,price=random.randint(100,900)) book_list.append(book) Book.objects.bulk_create(book_list)
2.django 分页器的用法
#django 分页器的使用 #总数据
book_lst=Book.objects.all()
#创建分页器对象
paginator = Paginator(book_lst,10) #参数 : 总数据,每页需要放的数据条数 print("总数据条数:",paginator.count) #
print("总共分了多少页:",paginator.num_pages) #
print("页码范围:",paginator.page_range) # range(1,21)
page =paginator.get_page(3) #取第 3 页的数据 # paginator.get_page(n) 拿到第 n 页 的数据
# for book in page:
# print(book) print("是否有下一页",page.has_next()) # 第3 页 有下一页 返回的是布尔值 :True
print("是否有上一页",page.has_previous()) # 第 3 页有上一页 返回的是布尔值 :True
print("下一页的数字:",page.next_page_number()) # 取到第3页的下一页数字4
print("上一页的数字:",page.previous_page_number()) #取第3页的上一页 数字 2
3. 实例
paginator =Paginator(data_list,10)
1.设计思路:
先从地址栏 发请求 的思路 开始考虑问题 http://127.0.0.1:8000/index/?page=3
地址栏 通过一个 page=1 的键值对 ,通过发get的请求给后端服务器, 后端通过 current_page= request.GET.get("page") 得到需要看的page数
通过 page_data = paginator .get_page(current_page) ,然后前端通过循环page_data 展示客户需要看的那一页数据
2. 设计 显示页码
后端逻辑:
book_list = Book.objects.all()
paginator = Paginator(book_list,2) current_page=int(request.GET.get("page",1))
page = paginator.get_page(current_page) # 如果页数十分多时,换另外一种显示方式 ,
if paginator.num_pages>11: #页面最多显示的页码数 11表示:需要显示的页面码总数 ,以及上一页,下一页,首页 ,尾页 if current_page-5<1:
page_range=range(1,12)
elif current_page+5>paginator.num_pages:
page_range=range(paginator.num_pages-10,paginator.num_pages+1)
else:
page_range=range(current_page-5,current_page+6)
else:
page_range=paginator.page_range
return render(request,"index.html",{"page":page,"page_range":page_range,"current_page":current_page})
模板HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <ul>
{% for book in page %}
<li>{{ book.title }}---{{ book.price }}</li>
{% endfor %}
</ul> <nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="?page=1" aria-label="Previous"><span aria-hidden="true">首页</span></a></li> {% if page.has_previous %}
<li><a href="?page={{ page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>
{% else %}
<li class="disabled"><a aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>
{% endif %} {% for num in page_range %}
{% if num == current_page %}
<li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
{% else %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %} {% endfor %} <li>
<a href="#" >
<span aria-hidden="true">下一页</span>
</a>
</li>
<li>
<a href="#" >
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</nav> </body>
</html>
2.django 分页器
from django.shortcuts import render
from .models import Book
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import random
# Create your views here.
def index(request): #批量创建数据
# book_list = []
#
# for i in range(1,101):
# book= Book(title="book_%s"%i,price=random.randint(100,600))
#
# book_list.append(book)
#
# Book.objects.bulk_create(book_list)
book_list = Book.objects.all()
current_page = request.GET.get("page") #实例化分页器 paginator = Paginator(book_list,9)
num_pages= paginator.num_pages #能分多少页
page_range = paginator.page_range # 页码范围
page = paginator.get_page(current_page)
show_books = page.object_list
print(page.has_previous()) #页码显示的个数 show_page_nums =11
show_page_nums = 11
if num_pages <show_page_nums: #num_pages<show_page_nums
#展示所有的页码
page_range = page_range
else:
#正常当前页算出左右的页面数:
half_num = int((show_page_nums-1)/2)
#分页数大于11时: num_pages>show_page_nums
#当前页或等于half_num就显示前面的11页
if int(current_page)<=half_num:
#就显示 前 show_page_nums
page_range = range(1,show_page_nums+1) elif (int(current_page)+half_num)>=num_pages:
#就显示最后 show_page_nums 页
page_range = range(1,num_pages+1)[-show_page_nums:]
else:
page_range = range((int(current_page)-half_num),(int(current_page)+half_num)+1) return render(request,"index.html",{"book_list":show_books,"page_range":page_range,"current_page":int(current_page),"page":page,})
后端逻辑
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
{% for book in book_list %}
<div>{{ book.title }}--------------{{ book.price }}</div>
{% endfor %} <nav aria-label="Page navigation">
<ul class="pagination">
<li>
{% if page.has_previous %}
<a href="?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
{% else %} <span aria-hidden="true" class="disabled"frd>上一页</span> {% endif %} </li>
{% for num in page_range %} {% if current_page == num %}
<li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
{% else %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %} <li>
{% if page.has_next %}
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
{% else %}
<span aria-hidden="true" class="disabled">下一页</span>
</a>
{% endif %} </li>
</ul>
</nav> </body>
</html>
前端显示页面
Django分页器和自定义分页器的更多相关文章
- Django分页器及自定义分页器
Django的分页器 view from django.shortcuts import render,HttpResponse # Create your views here. from app0 ...
- Django基础之自定义分页器
自定义分页器 针对批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便 针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理 分 ...
- django中的自定义分页器
1.什么是自定义分页器 当我们需要在前端页面展示的数据太多的时候,我们总不能将数据展示在一页上面吧!这时,我们就需要自定义一个分页器,将数据分成特定的页数进行展示,每一页展示固定条数的数据! 2.为什 ...
- django----Sweetalert bulk_create批量插入数据 自定义分页器
目录 一.Sweetalert使用AJAX操作 二.bulk_create 三.分页器 divmod 分页器组件 自定义分页器的使用 一.Sweetalert使用AJAX操作 sweetalert ...
- django自定义分页器
一 django 的分页器 1 批量创建数据 批量导入数据: Booklist=[] for i in range(100): Booklist.append(Book(title="boo ...
- Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数
Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...
- Python自定义-分页器
Python自定义-分页器 分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置. 1.设定每页显示数据条数 2.用户输入页码(第一页.第二页...) 3 ...
- 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...
- Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07
目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...
随机推荐
- nohup 让进程在后台可靠运行的几种方法
1. nohup nohup 无疑是我们首先想到的办法.顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号. nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即 ...
- Android Studio 快捷键、Debug的使用
https://blog.csdn.net/q908555281/article/details/49331371 1.快捷键 个人习惯常用快捷键 在Eclipse中常用的快捷键 ...
- 题解——洛谷P1962 斐波那契数列(矩阵乘法)
矩阵乘法加速线性递推的典型 大概套路就是先构造一个矩阵\( F \)使得另一初始矩阵\( A \)乘以\( F^{x} \)能够得出第n项 跑的飞快 虽然我也不知道那个矩阵要怎么构造 或许就像我使用了 ...
- springcloud问题随笔
http://www.cnblogs.com/EasonJim/p/8085120.html 1.调用其它服务返回could not be queued for execution and no fa ...
- Paper Reviews and Presentations
Copied from Advanced Computer Networks, Johns Hopkins University. Paper Reviews and Presentations Ea ...
- SAP按销售订单生产和标准结算配置及操作手册
SAP按销售订单生产和标准结算配置及操作手册 http://blog.sina.com.cn/s/blog_6787c0b80101a3tl.html SAP按销售订单生产和标准结算配置及操作手册 S ...
- JavaScript(ES5)知识点梳理
数据类型(null undefined number string boolean object)数据类型之间的相互转化(Boolean Number String parseInt parseFlo ...
- [luogu]P1852跳跳棋
题目重点是每次不能跳过两个棋子 即对于每一个棋子的状态(a,b,c) (a<b<c) 最多有两种移动的方式 1.中间往两边跳 (a,b,c)-->(2b-a,a,c)或(a,c,2b ...
- new和malloc的用法和区别
从以下几个方面总结下new和malloc的区别: 参考博客: https://blog.csdn.net/nie19940803/article/details/76358673 https://bl ...
- c# 通过反射输出成员变量以及成员变量的值
/*** @Author rexzhao* 工具类 仅限于* public variable*/using System.Collections;using System.Collections.Ge ...