WEB框架之Django实现分页功能
一 Paginator分页器
1 首先在数据库中生成大量数据
def index(request)
book_list = []
for i in rang(1000)
book = Book(title="book_%s" %i, price=i*i)
book_list.append(book)
Book.objects.bulk_create(book_list) # 批量插入数据
2 分页器中的主要方法
from django.core.paginator import Paginator paginator = Paginator(book_list,8) # 每页展示几条内容
print("count:",paginator.count) # 总页数
print("page_range",paginator.page_range) # 页码的列表
print("num_pages",paginator.num_pages) # 总页数
page1 = paginator.page(1) # 第1页的page对象
for i in page1 # 遍历第1页的所有数据对象
print(i) page2 = paginator.page(2)
print(page2.hax_next()) # 是否有下一页
print(page2.next_page_number()) # 下一页页码
print(page2.has_pervious()) # 是否有上一页
print(page2.pervious_page_number()) # 上一页的页码
3 实现页面分页
模板:
{% if current_page.has_previous %} 先判断是否有上一页,如果没有就把'上一页'关闭
<li>
<a href="?page={{ current_page_num|add:-1 }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %} {% for item in page_range %} {% if current_page_num == item %}
<li class="active"><a href="?page={{ item }}">{{ item }}</a></li>
{% else %}
<li><a href="?page={{ item }}">{{ item }}</a></li>
{% endif %}
{% endfor %} {% if current_page.has_next %}
<li>
<a href="?page={{ current_page_num|add:1 }}" aria-label="Next">
<span aria-hidden="true" class="put-right">»</span>
</a>
</li>
{% endif %}
视图函数:
book_list = Book.objects.all() # 获取全部数据
paginator = Paginator(book_list, 10) # 每页显示10条内容
current_page_num = int(request.GET.get("page", 1)) # 当前在哪一页 if paginator.num_pages > 11:
if current_page_num -5<1:
page_range = range(1,11)
elif current_page_num +5>paginator.num_pages:
page_range=range(paginator.num_pages-11, paginator.num _pages+1)
else:
page_range = range(current_page_num-5, current_page_num+6)
else:
page_range = paginator.page_range print("count:", paginator.count)
print("num_pages:", paginator.num_pages)
print("page_range:", page_range)
for i in page_range:
print(i)
try:
current_page = paginator.page(current_page_num) # 第一页的数据对象
print("object_list", current_page.object_list)
except:
current_page = paginator.page(1)
return render(request, 'index.html',locals())
二 自定义分页
1 直接在函数中实现分页
def get_data(req):
if req.metho == 'GET':
current_page = request.GET.get('page',1) # 获取用户传来的请求页面(相当于当前页面),默认是1
current_page = int(current_page)
# 制造切片
start = (current_page - 1) * 10
end = current_page * 10
data = models.User.objects.all()[start:end] # 一次取10条数据
# 总个数
total_count = models.Classes.objects.all().count()
# 用总个数和每页显示的个数相处,求商和余数,如果有余数总页码还需+1
v,a = divmod(total_count,10) # 相当于总页数
if a != 0:
v+=1
# 生成页码
page_list = []
# 如果是第一页那么上一页的功能就取消
if current_page == 1:
page_list.append('<a href="#">上一页</a>' %(current_page-1)
else:
page_list.append('<a href="/index?page=%s">上一页</a>' %(current_page-1)
# 判断并生成page_range
if v <= 11:
pager_range_start =1
ager_range_end = v
else:
if current_page <6:
pager_range_start = 1
pager_range_end = 11 +1
else:
pager_range_start = current_page -5
pager_range_end = current_page +6
if pager_range_end > v:
page_range_start = current_page - 10
pager_range_end = v +1 for i in range(pager_range_star,pager_range_end)
if i == current_page:
page_list.append('<a href="/index?page=%s" class=actice>%s</a>' %(i,i))
page_list.append('<a href="/index?page=%s">%s</a>' %(i,i)) # 如果当前页是最后一页那么下一页功能就取消
if current_page == v:
page_list.append('<a href="#">下一页</a>' %(current_page+1)
else:
page_list.append('<a href="/index?page=%s">下一页</a>' %(current_page+1) pager = "".join(pager_list)
return render(request,{'data':data,'str_page':pager})
2 将自定义的分页器封装成一个类
class PagerHandler:
def __inin__(self,total_count,current_page, base_url. per_page=10):
self.total_count = total_count
self.current_page = current_page
self.base_url = base_url
self.per_page = per_page def db_start(self):
return (self.current_page -1) * self.per_page def db_end(self):
return (self.current_page) * self.per_page def tootal_page(self):
v,a = divmod(total_count,10) # 相当于总页数
if a != 0:
v+=1
return v def pager_str(self): v = self.tootal_page()
# 生成页码
page_list = []
# 如果是第一页那么上一页的功能就取消
if self.current_page == 1:
page_list.append('<a href="#">上一页</a>' %(self.current_page-1)
else:
page_list.append('<a href="/%s?page=%s">上一页</a>' %(self.base_url,self.current_page-1) # 判断并生成page_range
if v <= 11:
pager_range_start =1
pager_range_end = v
else:
if current_page <6:
pager_range_start = 1
pager_range_end = 11 +1
else:
pager_range_start = self.current_page -5
pager_range_end = self.current_page +6
if pager_range_end > v:
page_range_start = self.current_page - 10
pager_range_end = v +1 for i in range(pager_range_star,pager_range_end)
if i == self.current_page:
page_list.append('<a href="/%s?page=%s" class=actice>%s</a>' %(self.base_url,i,i))
page_list.append('<a href="/%s?page=%s">%s</a>' %(self.base_url,i,i)) # 如果当前页是最后一页那么下一页功能就取消
if self.current_page == v:
page_list.append('<a href="#">下一页</a>' %(self.current_page+1)
else:
page_list.append('<a href="/%s?page=%s">下一页</a>' %(self.base_url,self.current_page+1)
pager = "".join(pager_list)
return pager
3 在视图函数中调用
def index(request)
if request.method == 'GET':
current_page = request.GET.get('page',1)
current_page = int(current_page)
# 数据总数
total_count = models.Classes.objects.all().count()
page_obj = PagerHandler(total_count,current_page,'/index/')
pager = page_obj.pager_str()
data = models.Classes.objects.all()[page_obj.db_start():page_obj.db_end()]
return render(request,'index.html',{'data':data,'pager':pager})
4 也页面中保留过滤条件班分页组件
class Pagination:
def __init__(self, data_num, current_page, params, url_prefix, per_page=10, max_show=11):
"""
进行初始化.
:param data_num: 数据总数
:param current_page: 当前页
:param url_prefix: 生成的页码的链接前缀
:param per_page: 每页显示多少条数据
:param max_show: 页面最多显示多少个页码
""" self.data_num = data_num
self.per_page = per_page
self.max_show = max_show
self.url_prefix = url_prefix # 把页码数算出来
self.page_num, more = divmod(data_num, per_page)
if more:
self.page_num += 1 try:
self.current_page = int(current_page)
except Exception as e:
self.current_page = 1
# 如果URL传过来的页码数是负数
if self.current_page <= 0:
self.current_page = 1
# 如果URL传过来的页码数超过了最大页码数
elif self.current_page > self.page_num:
self.current_page = self.page_num # 默认展示最后一页 # 页码数的一半 算出来
self.half_show = self.max_show // 2
# 如果数据总页码self.page_num<11 pager_page_count
if self.page_num <= self.max_show:
self.page_start = 1
self.page_end = self.page_num
else:
# 数据页码已经超过11
# 判断: 如果当前页 <= 5 self.half_show
if self.current_page <= self.half_show:
self.page_start = 1
self.page_end = self.max_show
else:
# 如果: 当前页+5 > 总页码
if (self.current_page + self.half_show) > self.page_num:
self.page_start = self.page_num - self.max_show + 1
self.page_end = self.page_num
else:
self.page_start = self.current_page - self.half_show
self.page_end = self.current_page + self.half_show import copy
self.params = params # {"page":"12","title_startwith":"py","id__gt":"5"} @property
def start(self):
# 数据从哪儿开始切
return (self.current_page - 1) * self.per_page @property
def end(self):
# 数据切片切到哪儿
return self.current_page * self.per_page def page_html(self):
# 生成页码
l = []
# 加一个首页
first_page = self.params
first_page['page'] = 1
l.append('<li><a href="{}?{}">首页</a></li>'.format(self.url_prefix, first_page.urlencode()))
# 加一个上一页
if self.current_page == 1:
l.append('<li class="disabled" ><a href="#">«</a></li>'.format(self.current_page))
else:
self.params['page'] = self.current_page - 1
l.append('<li><a href="{}?{}">«</a></li>'.format(self.url_prefix, self.params.urlencode())) for i in range(self.page_start, self.page_end + 1):
self.params['page'] = i
if i == self.current_page:
tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.url_prefix, self.params.urlencode(), i)
else:
tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.url_prefix, self.params.urlencode(), i)
l.append(tmp) # 加一个下一页
if self.current_page == self.page_num:
l.append('<li class="disabled"><a href="#">»</a></li>'.format(self.current_page))
else:
self.params['page'] = self.current_page + 1
l.append('<li><a href="{}?{}">»</a></li>'.format(self.url_prefix, self.params.urlencode()))
# 加一个尾页
last_page = self.params
last_page['page'] = self.page_num
l.append('<li><a href="{}?{}">尾页</a></li>'.format(self.url_prefix, last_page.urlencode()))
return "".join(l)
WEB框架之Django实现分页功能的更多相关文章
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- 两个Python web框架:Django & Tornado比较
就是说它作为 web 框架比 Django 简单,又支援异步 IO,且更不需要前端的 webserver ? 我已经混乱了, Tornado是 Nginx.Django.Node.js 的结合体?又或 ...
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
- Python开发【第十八篇】Web框架之Django【基础篇】
一.简介 Python下有许多款不同的 Web 框架,Django 是重量级选手中最有代表性的一位,许多成功的网站和APP都基于 Django. Django 是一个开放源代码的Web应用框架,由 P ...
- web框架和django基础(粗糙版)
web框架本质: 浏览器:socket客户端 服务器:socket服务端 1.自己写socket服务端(最傻) #!/usr/bin/env python ...
- Django准备知识-web应用、http协议、web框架、Django简介
一.web应用 Web应用程序是一种可以通过web访问的应用程序(web应用本质是基于socket实现的应用程序),程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 ...
- Web框架之Django_01初识(三大主流web框架、Django安装、Django项目创建方式及其相关配置、Django基础三件套:HttpResponse、render、redirect)
摘要: Web框架概述 Django简介 Django项目创建 Django基础必备三件套(HttpResponse.render.redirect) 一.Web框架概述: Python三大主流Web ...
- python web框架——扩展Django&tornado
一 Django自定义分页 目的:自定义分页功能,并把它写成模块(注意其中涉及到的python基础知识) models.py文件 # Create your models here. class Us ...
- python笔记-19 javascript补充、web框架、django基础
一.JavaScript的补充 1 正则表达式 1.1 test的使用 test 测试是否符合条件 返回true or false 1.2 exec的使用 exec 从字符串中截取匹配的字符 1.3 ...
随机推荐
- python函数基础:调用内置函数&定义函数
调用内置函数 有很多内置函数,在使用中需要积累.这里只举两个例子: 分别调用abs和数据类型转换,注意当入参类型错误时候会报错 ''' print('abs(-100)') abs(-100) pri ...
- Winform 各种属性、方法、控件
窗体是程序与用户交互的可视界面,窗体也是对象,窗体类定义了生成窗体的模版,实例化一个窗体类就产生了一个窗体. .NET框架类库的System.Windows.Forms命名空间中定义的Form类是所有 ...
- 2017面向对象程序设计(Java) 第1周学习指导及要求(2017.8.24-2017.8.27)
2017面向对象程序设计(Java) 第1周学习指导及要求(2017.8.24-2017.8.27) 学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 简单了解Java特点及 ...
- 11.8java课后动手动脑
package 动手动脑; import javax.swing.*; class AboutException { public static void main(String[] a) { int ...
- 仿造mongodb的存储方式存一些假数据
//存入数据 $data = json_encode($row); // 过滤 $data = addslashes($data); //读取数据 $falseData = stripslashes( ...
- U3D框架—单例框架
写程序应遵循的原则:高内聚(内容的聚合),低耦合(功能与功能之间的联系) 代码里尽量不要有冗余:既重复,没有用的代码 using System.Collections; using System.Co ...
- python网络编程之进程论
标签(空格分隔): 进程 什么是进程: 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu; 进程与程序的区别: 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程 注意: 需要强调的 ...
- backdoor-factory
启动backdoor-factory 寻找大于100字节的代码洞 执行的结果 查看适合的payload程序 iat_reverse_tcp_stager_threaded分片段注入方式 使用这种注入方 ...
- jenkins动态参数插件Dynamic Parameter安装及简单使用
插件安装: 1.先下载插件hpi文件到本地 jenkins插件下载地址 http://mirror.xmission.com/jenkins/plugins/ http://updates.jen ...
- sqlserver 查看当前连接数
参考 https://www.cnblogs.com/lumnm/archive/2009/08/29/1556349.html SELECT * FROM[Master].[dbo].[SYSPRO ...