一.Django 分页器

1.django的分页器基础版

(1)首先是基础数据分别为

from django.db import models

# Create your models here.
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)

models.py

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', views.Book.as_view())
]

urls.py

(2)基础版的视图函数

from django.shortcuts import render, redirect
from django.views import View # 导入view
from app01 import models # 导入模型
from django.core.paginator import Paginator # 导入django分页器
import random # Create your views here.
class Book(View):
def get(self, request):
# 法二:批量增加测试数据 效率块
# book_list = []
# for i in range(1, 101):
# # models.Book.objects.create(title="book_%s" % i, price=random.randint(20, 300)) # 法一:执行效率低
# book_list.append(models.Book(title="book_%s" % i, price=random.randint(20, 300)))
# models.Book.objects.bulk_create(book_list) # 批量新增数据
# 分页器的基本语法
# book_list = models.Book.objects.all()
# print(book_list) # QuerySet book对象
# # 实例化分页对象
# paginator = Paginator(book_list, 10)
# print("count:", paginator.count) # 数据的总数
# print("num_pages:", paginator.num_pages) # 分页的总页数
# print("page_range:",paginator.page_range) # 页数的范围列表
#
# page1 = paginator.get_page(1) # 获取第一页的所有数据
# for i in page1: # 遍历第一页的所有数据对象
# print(i)
# print(page1.object_list) # 第一页的所用数据
# page2 = paginator.get_page(2) # 获取第二页的所有数据
# print(page2.has_next()) # 是否有下一页
# print(page2.next_page_number()) # 下一页的页码
# print(page2.has_previous()) # 是否有上一页
# print(page2.previous_page_number()) # 上一页的页码
# 当get不存在的页数或者填写其他类型的数据时会报错
# page=paginator.page(22) # error:EmptyPage
# page=paginator.page("z") # error:PageNotAnInteger # ############# django分页器的基本使用 ##################
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 10) # 每页分的数量(数据量) current_page = int(
request.GET.get("page") if request.GET.get("page") and request.GET.get("page").isdigit() else 1) # 获取页码
page = paginator.get_page(current_page) # 获取当前页码的所有数据 return render(request, "book.html", {"paginator": paginator, "page": page, "current_page": current_page}) def post(self, request):
return redirect("/book/")

views.py

(3)最后是模板内容

<!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>
<h2>图书列表</h2>
<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">首页</a></li>
{% if page.has_previous %}
<li><a href="?page={{ page.previous_page_number }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">上一页</a></li>
{% endif %}
{% for num in paginator.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 %}
{% if page.has_next %}
<li><a href="?page={{ page.next_page_number }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">下一页</a></li>
{% endif %}
<li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
</ul>
</nav> </body>
</html>

book.html

2.进阶版分页器

上面的示例,看似已经完成了分页的效果,但是,如果我们把每页显示的数量改小一点看一下效果。

显然这样不是我们想要的

(1)进阶版视图函数

from django.shortcuts import render, redirect
from django.views import View # 导入view
from app01 import models # 导入模型
from django.core.paginator import Paginator # 导入django分页器
import random # Create your views here.
class Book(View):
def get(self, request):
# ############# django分页器的基本使用进阶版 ##################
# 分页器的基本语法
book_list = models.Book.objects.all() # 示例分页器对象
paginator = Paginator(book_list, 2) # 每页显示数据的数量
current_page = int(
request.GET.get("page") if request.GET.get("page") and request.GET.get("page").isdigit() else 1)
# 获取页码
page = paginator.get_page(current_page) # 获取当前页码的所有数据
# 默认按照11个页码展示 if paginator.num_pages > 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 # 默认是10个页码
# if paginator.num_pages > 10:
# if current_page - 4 < 1:
# page_range = range(1, 11)
# elif current_page + 5 > paginator.num_pages:
# page_range = range(paginator.num_pages - 9, paginator.num_pages + 1)
# else:
# page_range = range(current_page - 5, current_page + 5)
#
# else:
# page_range = paginator.page_range
return render(request, "book.html", {
'paginator': paginator, "current_page": current_page, "page": page, "page_range": page_range
})

views.py

(2)模板内容

<!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>
<h2>图书列表</h2>
<ul> {# {% for book in page %}#}
{# <li>{{ book.title }} --- {{ book.price }}</li>#}
{# {% endfor %}#}
{% for p in page %}
<li>{{ p }}</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">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% endif %} {# 页码#}
{# {% for num in paginator.page_range %}#}
{% 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 %} {# 下一页#}
{% if page.has_next %}
<li>
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% endif %} {# 尾页#}
<li>
<a href="?page={{ paginator.num_pages }}" aria-label="Next">
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</nav>
</body>
</html>

book.html

显示的效果为:

3.页码数设置奇数偶数优化版

(1)视图函数

from django.shortcuts import render
from django.views import View # 导入view
from app01 import models # 导入模型
from django.core.paginator import Paginator # 导入django分页器
import math
# Create your views here.
# 页码数设置奇数偶数优化版:只要设置page_num 页码即可,奇数偶数都兼容
class Book(View):
def get(self, request):
# ############# django分页器的基本使用进阶版 ##################
# 分页器的基本语法
book_list = models.Book.objects.all() # 示例分页器对象
paginator = Paginator(book_list, 2) # 每页显示数据的数量
current_page = int(
request.GET.get("page") if request.GET.get("page") and request.GET.get("page").isdigit() else 1)
# 获取页码
page = paginator.get_page(current_page) # 获取当前页码的所有数据
page_num = 11 # 设置页码个数,设置需要的个数可以为奇数,偶数
if paginator.num_pages > page_num: if current_page - math.floor(page_num/2) < 1:
page_range = range(1, page_num+1)
elif current_page + math.ceil((page_num-1)/2) > paginator.num_pages:
page_range = range(paginator.num_pages - (page_num-1), paginator.num_pages + 1)
else:
page_range = range(current_page - math.ceil((page_num-1)/2), current_page + math.floor((page_num+1)/2))
else:
page_range = paginator.page_range return render(request, "book.html", {
'paginator': paginator, "current_page": current_page, "page": page, "page_range": page_range
})

views.py

(2)模板内容

模板内容同上2的模板内容

效果图:奇数

效果图:偶数

二.自定制分页器

前提是已经在一上面的基础上,对视图和模板进行修改

1. 自定制分页器

(1)自定致分页器类

class Paginator:
def __init__(self, current_page, all_count, per_page=10, max_page_num=11):
"""
封装分页相关数据
:param current_page: 当前页码
:param all_count: 数据库中的数据总条数
:param per_page: 每个页面显示的数据条数
:param max_page_num: 最多显示的页码个数
:param num_pages: 通过总条数/每个页面显示的条数,求出总页数
"""
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_count = all_count
self.per_page = per_page # 计算总页数
num_pages, temp = divmod(all_count, per_page)
if temp:
num_pages += 1
self.num_pages = num_pages self.max_page_num = max_page_num #
self.page_count_half = int((self.max_page_num - 1) / 2) #
"""
self.num_pages=100
per_page=8 current_page =1 [0:8]
current_page =2 [8:16]
current_page =3 [16:24]
[(current_page-1)*per_page:current_page*per_page ] """ @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):
# 如果总页数小于self.max_page_num(最多显示的页码个数)
if self.num_pages <= self.max_page_num:
page_start = 1
page_end = self.num_pages + 1
else:
# 如果当前页码<=页面上最多显示11/2个页码时
if self.current_page <= self.page_count_half:
page_start = 1
page_end = self.max_page_num + 1
# 如果当前页码+最多显示11/2 大于 总页数时
elif self.current_page + self.page_count_half > self.num_pages:
page_start = self.num_pages - self.max_page_num + 1
page_end = self.num_pages + 1
else:
page_start = self.current_page - self.page_count_half
page_end = self.current_page + self.page_count_half + 1 page_html_list = [] # 首页
first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=1">首页</a></li>'
page_html_list.append(first_page) # 上一页
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1, )
page_html_list.append(prev_page) # 显示页码
for i in range(page_start, page_end):
if self.current_page == i:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
page_html_list.append(temp) # 下一页
if self.current_page >= self.num_pages:
next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1)
page_html_list.append(next_page) # 尾页
last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % self.num_pages
page_html_list.append(last_page) return "".join(page_html_list)

(2)视图函数

from django.shortcuts import render, redirect
from django.views import View # 导入view
from app01 import models # 导入模型
from app01.page import Paginator # 导入自定制的分页器 class Book(View):
def get(self, request):
book_list = models.Book.objects.all()
current_page = request.GET.get('page')
# 当前页数 数据总数 每页数据量 分页量
paginator = Paginator(current_page, book_list.count(), 6, 11)
book_list = book_list[paginator.start: paginator.end] return render(request, "book.html",
{"book_list": book_list, "paginator": paginator, "current_page": current_page})

views.py

(3)模板函数

<!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>
<h2>图书列表</h2>
<ul>
{% for book in book_list %}
<li>{{ book.title }} --- {{ book.price }}</li>
{% endfor %}
</ul> {{ paginator.page_html|safe }} </body>
</html>

book.html

效果图:

2.终极版本分页器

为什么需要终极版本呢,因为上面都还有些缺陷,那就是如果请求头还有其他数据,换页后会消失。

(1)终极版自定义分页类

class Paginator:
def __init__(self, request, current_page, all_count, per_page=10, max_page_num=13):
"""
封装分页相关数据
:param current_page: 当前页码
:param all_count: 数据库中的数据总条数
:param per_page: 每个页面显示的数据条数
:param max_page_num: 最多显示的页码个数
:param num_pages: 通过总条数/每个页面显示的条数,求出总页数
"""
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_count = all_count
self.per_page = per_page # 计算总页数
num_pages, temp = divmod(all_count, per_page)
if temp:
num_pages += 1
self.num_pages = num_pages self.max_page_num = max_page_num #
self.page_count_half = int((self.max_page_num - 1) / 2) # import copy
self.url_args = copy.deepcopy(request.GET)
print(self.url_args.urlencode()) """
self.num_pages=100
per_page=8 current_page =1 [0:8]
current_page =2 [8:16]
current_page =3 [16:24]
[(current_page-1)*per_page:current_page*per_page ] """ @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):
# 如果总页数小于self.max_page_num(最多显示的页码个数)
if self.num_pages <= self.max_page_num:
page_start = 1
page_end = self.num_pages + 1
else:
# 如果当前页码<=页面上最多显示11/2个页码时
if self.current_page <= self.page_count_half:
page_start = 1
page_end = self.max_page_num + 1
# 如果当前页码+最多显示11/2 大于 总页数时
elif self.current_page + self.page_count_half > self.num_pages:
page_start = self.num_pages - self.max_page_num + 1
page_end = self.num_pages + 1
else:
page_start = self.current_page - self.page_count_half
page_end = self.current_page + self.page_count_half + 1 page_html_list = [] # 首页
self.url_args['page'] = 1
first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?%s">首页</a></li>' % (self.url_args.urlencode())
page_html_list.append(first_page) # 上一页
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
else:
self.url_args['page'] = self.current_page - 1
prev_page = '<li><a href="?%s">上一页</a></li>' % (self.url_args.urlencode(), )
page_html_list.append(prev_page) # 显示页码
for i in range(page_start, page_end):
self.url_args['page'] = i
if self.current_page == i:
temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
else:
temp = '<li><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
page_html_list.append(temp) # 下一页
if self.current_page >= self.num_pages:
next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
else:
self.url_args['page'] = self.current_page + 1
next_page = '<li><a href="?%s">下一页</a></li>' % (self.url_args.urlencode(), )
page_html_list.append(next_page) # 尾页
self.url_args['page'] = self.num_pages
last_page = '<li><a href="?%s">尾页</a></li></ul></nav>' % self.url_args.urlencode()
page_html_list.append(last_page) return "".join(page_html_list)

page.py

(2)视图函数

from django.shortcuts import render, redirect
from django.views import View # 导入view
from app01 import models # 导入模型
from app01.page import Paginator # 导入自定制的分页器
class Book(View):
def get(self, request):
book_list = models.Book.objects.all()
current_page = request.GET.get('page')
paginator = Paginator(request, current_page, book_list.count(), 6, 11)
book_list = book_list[paginator.start: paginator.end] return render(request, "book.html", {"book_list": book_list, "paginator": paginator, "current_page": current_page})

views.py

(3)模板函数

模板函数同上即可

Django 学习组件分页器与自定制分页器的更多相关文章

  1. Django学习(3)模板定制

    在Django学习(一)一首情诗中,views.py中HTML被直接硬编码在代码之中,虽然这样便于解释视图是如何工作的,但直接将HTML硬编码到视图却不算一个好主意.因为: 对页面设计进行的任何改变都 ...

  2. Django学习——分页器基本使用、分页器终极用法、forms组件之校验字段、forms组件之渲染标签、forms组件全局钩子,局部钩子

    内容 1 分页器基本使用 2 分页器终极用法 3 forms组件之校验字段 1 前端 <!DOCTYPE html> <html lang="en"> &l ...

  3. [Django高级之批量插入数据、分页器组件]

    [Django高级之批量插入数据.分页器组件] 批量插入数据 模板层models.py from django.db import models class Books(models.Model): ...

  4. django之ajax结合sweetalert使用,分页器和bulk_create批量插入 07

    目录 sweetalert插件 bulk_create 批量插入数据 分页器 简易版本的分页器的推导 自定义分页器的使用(组件) sweetalert插件 有这么一个需求: ​ 当用户进行一个删除数据 ...

  5. Django学习笔记(13)——Django的用户认证(Auth)组件,视图层和QuerySet API

    用户认证组件的学习 用户认证是通过取表单数据根数据库对应表存储的值做比对,比对成功就返回一个页面,不成功就重定向到登录页面.我们自己写的话当然也是可以的,只不过多写了几个视图,冗余代码多,当然我们也可 ...

  6. Django学习笔记(14)——AJAX与Form组件知识补充(局部钩子和全局钩子详解)

    我在之前做了一个关于AJAX和form组件的笔记,可以参考:Django学习笔记(8)——前后台数据交互实战(AJAX):Django学习笔记(6)——Form表单 我觉得自己在写Django笔记(8 ...

  7. Django学习之十二:Cache 缓存组件

    目录 Django Cache 缓存组件 缓存逻辑伪代码 配置缓存源 可配置参数说明 01. Django的默认缓存 02. 基于Redis的django-redis 03. 自定义cache 04. ...

  8. Django学习之八:forms组件【对form舒心了】

    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...

  9. Django学习笔记(12)——分页功能

    这一篇博客记录一下自己学习Django中分页功能的笔记.分页功能在每个网站都是必要的,当页面因需要展示的数据条目过多,导致无法全部显示,这时候就需要采用分页的形式进行展示. 分页在网站随处可见,下面展 ...

随机推荐

  1. static关键字 weak关键字

    1.static关键字 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart){ ...} 在函数前面加了一个stati ...

  2. PHP转换oracle数据库的date类型

    今天圣诞节啊,圣诞节快乐啊! 最近遇到一个很纠结的事,就是我在plsql里面查的是这样的,很正常, 但是我用程序查出来就是这样的,啊啊啊,真是崩溃啊 但是我传数据需要上面那种格式,而且我对oracle ...

  3. Node.js Learning Notes

    简介 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动I/O服务 ...

  4. fiddler的代理设置

    fiddler通过监听系统的8888端口实现对系统浏览器发出的http报文进行截获监听,因此要使fiddler能够监听到浏览器数据,需要对浏览器设置代理端口 浏览器 <--8888端口代理--& ...

  5. C语言:有序递增链表的插入问题。

    //已建立一个带头节点的单向链表,链表中的各结点按结点数据域中的数据递增有序连接.fun函数:把形参x的值放入一个新结点并插入链表中,使插入的各个数据域的数据仍保持递增有序. #include < ...

  6. vCPU 和 CPU 的关系

    vCPU 和 pCPU 的关系不是数量,当被底层虚拟化之后,任何一个 vCPU 都是用到所有的 pCPU 核心总体的百分比,不是某一个核心这么去看的,并没有对应的关系,也不是一个很绝对的分配到具体某个 ...

  7. Vue——手机号、验证码登录(设置按钮60s禁用倒计时)

    最近在做一个Vue项目,前端通过手机号.验证码登录,获取验证码按钮需要设置60s倒计时(点击一次后,一分钟内不得再次点击).先看一下效果图: 输入正确格式的手机号码后,“获取验证码”按钮方可点击:点击 ...

  8. C++11特性中的stoi、stod

    本文摘录柳神笔记:   使⽤ stoi . stod 可以将字符串 string 转化为对应的 int 型. double 型变量,这在字符串处理的很 多问题中很有帮助-以下是示例代码和⾮法输⼊的处理 ...

  9. 十八、sun JPA理解及使用

    1.JPA理解及实现:    JPA(Java Persistence API)作为Java EE 5.0平台标准的ORM规范,将得到所有Java EE服务器的支持,是SUN在充分吸收现有ORM框架的 ...

  10. 刷题62. Unique Paths

    一.题目说明 题目62. Unique Paths,在一个m*n矩阵中,求从左上角Start到右下角Finish所有路径.其中每次只能向下.向右移动.难度是Medium! 二.我的解答 这个题目读读题 ...