一、Django的内置分页器(paginator)

view

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): '''
批量导入数据: Booklist=[]
for i in range(100):
Booklist.append(Book(title="book"+str(i),price=30+i*i))
Book.objects.bulk_create(Booklist)
''' '''
分页器的使用: book_list=Book.objects.all() paginator = Paginator(book_list, 10) print("count:",paginator.count) #数据总数
print("num_pages",paginator.num_pages) #总页数
print("page_range",paginator.page_range) #页码的列表 page1=paginator.page(1) #第1页的page对象
for i in page1: #遍历第1页的所有数据对象
print(i) print(page1.object_list) #第1页的所有数据 page2=paginator.page(2) print(page2.has_next()) #是否有下一页
print(page2.next_page_number()) #下一页的页码
print(page2.has_previous()) #是否有上一页
print(page2.previous_page_number()) #上一页的页码 # 抛错
#page=paginator.page(12) # error:EmptyPage 超过页码范围 #page=paginator.page("z") # error:PageNotAnInteger 非法页码值
  
#page = page_obj.page(-1) #That page number is less than 1 ,也是EmptyPage的错误,页码不能为负数,最少也是1
''' book_list=Book.objects.all() paginator = Paginator(book_list, 10) #按照每页显示10条来计算
page = request.GET.get('page',1) #将来访问的url是这样的 http://127.0.0.1:8000/路径/?page=1
currentPage=int(page) try:
print(page)
book_list = paginator.page(page)
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages) return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container"> <h4>分页器</h4>
<ul> {% for book in book_list %}
<li>{{ book.title }} -----{{ book.price }}</li>
{% endfor %} </ul> <ul class="pagination" id="pager"> {% if book_list.has_previous %}
<li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %} {% for num in paginator.page_range %} {% if num == currentPage %}
<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% endif %}
{% endfor %} {% if book_list.has_next %}
<li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %} </ul>
</div> </body>
</html>

扩展

from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
def show(request): book_objs = models.Book.objects.all()
page_obj = Paginator(book_objs,1)
print('数据总数',page_obj.count)
print('总页数',page_obj.num_pages)
print('页码列表',page_obj.page_range) page1 = page_obj.page(1)
for i in page1:
print(i)
print(page1.object_list)
page2 = page_obj.page(2) print(page2.has_previous())
print(page2.has_next())
print(page2.next_page_number())
print(page2.previous_page_number())
# page = page_obj.page(-1)
page_num = request.GET.get('page',1) try:
current_page_num = int(page_num)
page_num_data = page_obj.page(current_page_num)
except PageNotAnInteger:
current_page_num = 1
page_num_data = page_obj.page(current_page_num)
except EmptyPage:
current_page_num = page_obj.num_pages
page_num_data = page_obj.page(current_page_num)
except Exception:
current_page_num = 1
page_num_data = page_obj.page(current_page_num)
if page_obj.num_pages > 11: #扩展,如果总的页码数大于了11,我们就不把所有的页码数显示出来了,只显示其中11个页面,当前页左边5个,右边5个
if current_page_num - 5 < 1:
pageRange = range(1,12)
elif current_page_num + 5 > page_obj.num_pages:
pageRange = range(page_obj.num_pages-10,page_obj.num_pages+1)
else:
pageRange = range(current_page_num - 5,current_page_num + 6) else:
pageRange = page_obj.page_range book_objs = page_num_data
return render(request,'show.html',{'book_objs':book_objs,'current_page_num':current_page_num,'page_obj':page_obj,'pageRange':pageRange})

  show.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body> <h1>数据展示</h1>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>价格</th>
<th>性别</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book_obj in book_objs %}
<tr>
<td>{{ book_obj.pk }}</td>
<td>{{ book_obj.title }}</td>
<td>{{ book_obj.price }}</td>
<td>{{ book_obj.get_sex_display }}</td>
<td>{{ book_obj.publishDate|date:'Y-d-m' }}</td>
<td>{{ book_obj.publish.name }}</td>
<td>
{% for author in book_obj.authors.all %}
{{ author.name }}
{% endfor %} </td>
<td>
<a class="btn btn-warning" href="{% url 'edit_book' book_obj.pk %}">编辑</a>
<a class="btn btn-danger" href="{% url 'delete_book' book_obj.pk %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul class="pagination" id="pager">
{% if book_objs.has_previous %}
<li class="previous"><a href="/show/?page={{ book_objs.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="javascript:void(0)">上一页</a></li>
{% endif %}
<!--{% for num in page_obj.page_range %}-->
{% for num in pageRange %}
{% if num == current_page_num %}
<li class="item active"><a href="/show/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/show/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %}
{% if book_objs.has_next %}
<li class="next"><a href="/show/?page={{ book_objs.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %} </ul>
</div>
</div> </div> </body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html>

  model.py文件内容:

from django.db import models

# Create your models here.

class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid")
def __str__(self):
return self.name
class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64) class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField()
def __str__(self):
return self.name class Book(models.Model): nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32) publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to="Publish",to_field="nid")
authors=models.ManyToManyField(to='Author',)
def __str__(self):
return self.title

二、自定义分页

  当数据库中数据有很多,我们通常会在前端页面做分页展示。

  分页的数据可以在前端页面实现,也可以在后端实现分页。

  后端实现分页的原理就是每次只请求一页数据。

  准备工作

  我们使用脚本批量创建一些测试数据(将下面的代码保存到bulk_create.py文件中放到Django项目的根目录,直接执行即可。):

import os

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings") import django
django.setup() from app01 import models
bulk_obj = (models.Publisher(name='第{}出版社'.format(i)) for i in range(300))
models.Publisher.objects.bulk_create(bulk_obj) #批量添加,注意写法

  看下面几个版本的分页:

def publisher_list(request):
# 从URL中取当前访问的页码数
try:
current_page = int(request.GET.get('page'))
except Exception as e:
# 取不到或者页码数不是数字都默认展示第1页
current_page = 1
# 总数据量
total_count = models.Publisher.objects.count()
# 定义每页显示多少条数据
per_page = 10
# 计算出总页码数
total_page, more = divmod(total_count, per_page)
if more:
total_page += 1
# 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
max_show = 11
half_show = max_show // 2
# 计算一下页面显示的页码范围
if total_page <= max_show: # 总页码数小于最大显示页码数
page_start = 1
page_end = total_page
elif current_page + half_show >= total_page: # 右边越界
page_end = total_page
page_start = total_page - max_show
elif current_page - half_show <= 1: # 左边越界
page_start = 1
page_end = max_show
else: # 正常页码区间
page_start = current_page - half_show
page_end = current_page + half_show
# 数据索引起始位置
data_start = (current_page-1) * per_page
data_end = current_page * per_page publisher_list = models.Publisher.objects.all()[data_start:data_end] # 生成页面上显示的页码
page_html_list = []
page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
# 加首页
first_li = '<li><a href="/publisher_list/?page=1">首页</a></li>'
page_html_list.append(first_li)
# 加上一页
if current_page == 1:
prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
else:
prev_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(current_page - 1)
page_html_list.append(prev_li)
for i in range(page_start, page_end + 1):
if i == current_page:
li_tag = '<li class="active"><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
else:
li_tag = '<li><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
page_html_list.append(li_tag)
# 加下一页
if current_page == total_page:
next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
else:
next_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(current_page + 1)
page_html_list.append(next_li)
# 加尾页
page_end_li = '<li><a href="/publisher_list/?page={}">尾页</a></li>'.format(total_page)
page_html_list.append(page_end_li)
page_html_list.append('</ul></nav>')
page_html = "".join(page_html_list)
return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})
class Pagination(object):
"""自定义分页(Bootstrap版)"""
def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
"""
:param current_page: 当前请求的页码
:param total_count: 总数据量
:param base_url: 请求的URL
:param per_page: 每页显示的数据量,默认值为10
:param max_show: 页面上最多显示多少个页码,默认值为11
"""
try:
self.current_page = int(current_page)
except Exception as e:
# 取不到或者页码数不是数字都默认展示第1页
self.current_page = 1
# 定义每页显示多少条数据
self.per_page = per_page
# 计算出总页码数
total_page, more = divmod(total_count, per_page)
if more:
total_page += 1
self.total_page = total_page
# 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
self.max_show = max_show
self.half_show = max_show // 2
self.base_url = base_url @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):
# 计算一下页面显示的页码范围
if self.total_page <= self.max_show: # 总页码数小于最大显示页码数
page_start = 1
page_end = self.total_page
elif self.current_page + self.half_show >= self.total_page: # 右边越界
page_end = self.total_page
page_start = self.total_page - self.max_show
elif self.current_page - self.half_show <= 1: # 左边越界
page_start = 1
page_end = self.max_show
else: # 正常页码区间
page_start = self.current_page - self.half_show
page_end = self.current_page + self.half_show
# 生成页面上显示的页码
page_html_list = []
page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
# 加首页
first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
page_html_list.append(first_li)
# 加上一页
if self.current_page == 1:
prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
else:
prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(
self.base_url, self.current_page - 1)
page_html_list.append(prev_li)
for i in range(page_start, page_end + 1):
if i == self.current_page:
li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
else:
li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
page_html_list.append(li_tag)
# 加下一页
if self.current_page == self.total_page:
next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
else:
next_li = '<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(
self.base_url, self.current_page + 1)
page_html_list.append(next_li)
# 加尾页
page_end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
page_html_list.append(page_end_li)
page_html_list.append('</ul></nav>')
return "".join(page_html_list)
def publisher_list(request):
# 从URL中取当前访问的页码数
current_page = int(request.GET.get('page'))
# 比len(models.Publisher.objects.all())更高效
total_count = models.Publisher.objects.count()
page_obj = Pagination(current_page, total_count, request.path_info)
data = models.Publisher.objects.all()[page_obj.start:page_obj.end]
page_html = page_obj.page_html()
return render(request, "publisher_list.html", {"publisher_list": data, "page_html": page_html})

  再来一版django内置分页器的分页

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger L = []
for i in range(999):
L.append(i) def index(request):
current_page = request.GET.get('p') paginator = Paginator(L, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
try:
posts = paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts})
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
{% for item in posts %}
<li>{{ item }}</li>
{% endfor %}
</ul> <div class="pagination">
<span class="step-links">
{% if posts.has_previous %}
<a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
</span>
{% if posts.has_next %}
<a href="?p={{ posts.next_page_number }}">Next</a>
{% endif %}
</span> </div>
</body>
</html>

13.Django基础之django分页的更多相关文章

  1. day 65 Django基础之django分页

      Django基础之django分页   一.Django的内置分页器(paginator) view from django.shortcuts import render,HttpRespons ...

  2. day 61 Django基础之django分页

      Django基础之django分页 一.Django的内置分页器(paginator) view   from django.shortcuts import render,HttpRespons ...

  3. Django基础06篇 分页

    1.导入Django自带的分页类 from django.core.paginator import Paginator 2.分页类的使用 def index(request): # return H ...

  4. django基础知识之分页:

    分页 Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中 Paginator对象 Paginator(列表,int):返回分页对象,参数为列表数据, ...

  5. Django基础之django分页

    一.Django的内置分页器(paginator) view from django.shortcuts import render,HttpResponse # Create your views ...

  6. django基础 -- 2. django初识

    一.模块渲染  jinja2 实现简单的字符串替换(动态页面) 1.下载 pip install jinja2 示例 : html文件中 <!DOCTYPE html> <html ...

  7. 【django基础】django接口 异步ajax请求 导出数据库成excel表(包裹前端后端)

    py文件: from django.utils.http import urlquote from rest_framework.views import APIView from django.sh ...

  8. 老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分

    老师的blog整理 python基础部分: 宝哥blog: https://www.cnblogs.com/guobaoyuan/ 开哥blog: https://home.cnblogs.com/u ...

  9. 老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分

    老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分   老师的blog整理 python基础部分: 宝哥blog: https://www.cnblogs.com/gu ...

随机推荐

  1. lightoj 1119 - Pimp My Ride(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1119 题解:状压dp存一下车有没有被搞过的状态就行. #include < ...

  2. yzoj P2345 战争 题解

    纯数论 30分:纯暴力,直接模拟判断t秒后,判断hp是否小于0 60分: atk>=h,就是一炮一个,那么军队会在min(n,t)秒之后停止攻击,那么总伤害就是a[n+(n-1) +(n-2)+ ...

  3. 解决flutter:unable to find valid certification path to requested target 的问题

    1.问题 周末在家想搞搞flutter,家里电脑是windows的,按照官网教程一步步安装好以后,创建flutter工程,点击运行,一片红色弹出来,WTF? PKIX path building fa ...

  4. Wamp 新增php版本 教程

    a.php版本下载:https://windows.php.net/download b.如果是apache环境下请认准  Thread Safe  版本 下载解压zip c.调整文件名为 php7. ...

  5. ubuntu下创建定时任务的两种方式及常见问题解决方案

    创建定时任务的目的就是摆脱人为对程序重复性地运行. 0. 首先用下面的指令检查你是否安装crontab, crontab -l 如果本身就有的话,那么出现如下指令 LC_CTYPE="zh_ ...

  6. 小白学Python-S3-day04-用户信息的增删改查、变更权限

    一.用户信息 文件中每一行就是用户的详细信息,每一行是按照冒号为分隔符分成七段 第一段用户名,第二段密码占位符,第三段UID,第四段GID,第五段是描述信息,第六段是家目录.第七段是 是否 可以登录操 ...

  7. IDEA中运行测试方法

    1. 2. 3. 4. 5.

  8. Tomcat9控制台中文乱码的解决方案

    1.网上大部分都是这种方法 注释掉 tomcat 9 安装目录下的conf里的 logging.properties 找到 java.util.logging.ConsoleHandler.encod ...

  9. .Net基础篇_学习笔记_第八天_复杂数据类型(常量/枚举/结构)

    1.常量: 声明的常量的语法:const 变量类型 变量名=值;最大的特点就是,声明了常量后,就不能再被重新赋值. 2.枚举 语法:[public] enum 枚举名{ 值1, 值2, 值3, ... ...

  10. Flink 从 0 到 1 学习 —— 如何自定义 Data Sink ?

    前言 前篇文章 <从0到1学习Flink>-- Data Sink 介绍 介绍了 Flink Data Sink,也介绍了 Flink 自带的 Sink,那么如何自定义自己的 Sink 呢 ...