Django 学习组件分页器与自定制分页器
一.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">«</span>
- </a>
- </li>
- {% else %}
- <li class="disabled">
- <a href="javascript:void(0);" aria-label="Previous">
- <span aria-hidden="true">«</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">»</span>
- </a>
- </li>
- {% else %}
- <li class="disabled">
- <a href="javascript:void(0);" aria-label="Next">
- <span aria-hidden="true">»</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 学习组件分页器与自定制分页器的更多相关文章
- Django学习(3)模板定制
在Django学习(一)一首情诗中,views.py中HTML被直接硬编码在代码之中,虽然这样便于解释视图是如何工作的,但直接将HTML硬编码到视图却不算一个好主意.因为: 对页面设计进行的任何改变都 ...
- Django学习——分页器基本使用、分页器终极用法、forms组件之校验字段、forms组件之渲染标签、forms组件全局钩子,局部钩子
内容 1 分页器基本使用 2 分页器终极用法 3 forms组件之校验字段 1 前端 <!DOCTYPE html> <html lang="en"> &l ...
- [Django高级之批量插入数据、分页器组件]
[Django高级之批量插入数据.分页器组件] 批量插入数据 模板层models.py from django.db import models class Books(models.Model): ...
- django之ajax结合sweetalert使用,分页器和bulk_create批量插入 07
目录 sweetalert插件 bulk_create 批量插入数据 分页器 简易版本的分页器的推导 自定义分页器的使用(组件) sweetalert插件 有这么一个需求: 当用户进行一个删除数据 ...
- Django学习笔记(13)——Django的用户认证(Auth)组件,视图层和QuerySet API
用户认证组件的学习 用户认证是通过取表单数据根数据库对应表存储的值做比对,比对成功就返回一个页面,不成功就重定向到登录页面.我们自己写的话当然也是可以的,只不过多写了几个视图,冗余代码多,当然我们也可 ...
- Django学习笔记(14)——AJAX与Form组件知识补充(局部钩子和全局钩子详解)
我在之前做了一个关于AJAX和form组件的笔记,可以参考:Django学习笔记(8)——前后台数据交互实战(AJAX):Django学习笔记(6)——Form表单 我觉得自己在写Django笔记(8 ...
- Django学习之十二:Cache 缓存组件
目录 Django Cache 缓存组件 缓存逻辑伪代码 配置缓存源 可配置参数说明 01. Django的默认缓存 02. 基于Redis的django-redis 03. 自定义cache 04. ...
- Django学习之八:forms组件【对form舒心了】
目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...
- Django学习笔记(12)——分页功能
这一篇博客记录一下自己学习Django中分页功能的笔记.分页功能在每个网站都是必要的,当页面因需要展示的数据条目过多,导致无法全部显示,这时候就需要采用分页的形式进行展示. 分页在网站随处可见,下面展 ...
随机推荐
- numpy函数hstack,vstack,dstack简介
vstack.hstack和dstack都用于把几个小数组合并成一个大数组.它们的差别是小数组的元素在大数组中的排列顺序有所不同.把两部手机摆到一起有几种方式?水平的左右排列,垂直的上下排列,还可以把 ...
- 总结String类的常用方法
总结String类的常用方法 1. 获取字符串长度 public int length() 2. 获取字符串某一位置的字符 public char charAt(int index) 注意:字符串中第 ...
- mysql错误问题处理
问题1.mysql 黑窗口出现错误 无法启动此应用程序 ,计算机中丢失MSVCP120.DLL,请重新安装 因为是从虚拟机上安装的新的系统,所以dos窗口输入mysql -v的时候出现了上述的错误,之 ...
- 使用JavaScript获取样式的属性值
1 . 在js中可以使用style属性来获取样式的属性值(只能获取内联样式的属性值) 语法格式为: HTML元素.style.样式属性; 2 . 在IE浏览器中,使用currentStyle来获取 ...
- VS2017中遇到不存在从string到const char*的转换函数的解决方法
使用c_str()函数 c_str函数的返回值是const char*. c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同. 这是为了与c语言兼容,在c语言中没有stri ...
- 应用 AddressSanitizer 发现程序内存错误
作为 C/ C++ 工程师,在开发过程中会遇到各类问题,最常见便是内存使用问题,比如,越界,泄漏.过去常用的工具是 Valgrind,但使用 Valgrind 最大问题是它会极大地降低程序运行的速度, ...
- 5_7 丑数(UVa136)<priority_queue的使用>
Ugly Number的定义为:该数之质因数必须为2,3或5,当然了,依照惯例,1也算是Ugly Number.在此列举一串数列:1,2,3,4,5,6,8,9,10,12,15这些就是前11个Ugl ...
- pytest-conftest.py作用范围
1.conftest.py解释 conftest.py是pytest框架里面一个很重要的东西,它可以在这个文件里面编写fixture,而这个fixture的作用就相当于我们unittest框架里面的s ...
- typo3 网站迁移
最近再弄这个typo3,虽然说看不怎么动,但是迁移嘛,最笨的办法就是整体过去,就是数据量太大了,哈哈,我先写一下我的笨办法: 注意:每个版本的typo3对php,mysql,apache的版本都有要求 ...
- redis基本操作,基于StringRedisTemplate,存储,取值,设置超时时间,获取超时时间,插入list操作
@Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("/test") void test ...