Django 自定义分页器的实现代码


Posted in Python onNovember 24, 2019

为什么要实现分页?

在大部分网站中分页的功能都是必要的,尤其是在后台管理中分页更是不可或缺

分页能带给用户更好的体验,也能减轻服务器的压力

对于分页来说,有许多方法都可以实现

例如把数据全部读取出来在前端用javascript实现,但这样一次请求全部数据服务器压力很大,

还有就是在后端实现,每一次请求部分数据显示

分页需求:

1. 每页显示的多少条数据

2. 页面显示多少个页码

3. 上一页和下一页

4. 首页和尾页

效果演示:

Django 自定义分页器的实现代码

代码实现:

分页类封装:

在我的app下创建一个page.py文件,进行封装,我是先在我的app下创建了一个utils文件再创建page.py

Django 自定义分页器的实现代码

class Pagination(object):

  def __init__(self, current_page_num, all_count, request, per_page_num=10, pager_count=11):
    """
    封装分页相关数据
    :param current_page_num: 当前访问页的数字
    :param all_count:  分页数据中的数据总条数
    :param per_page_num: 每页显示的数据条数
    :param pager_count: 最多显示的页码个数
    """
    try:
      current_page_num = int(current_page_num)
    except Exception as e:
      current_page_num = 1

    if current_page_num < 1:
      current_page_num = 1

    self.current_page_num = current_page_num

    self.all_count = all_count
    self.per_page_num = per_page_num

    # 实际总页码
    all_pager, tmp = divmod(all_count, per_page_num)
    if tmp:
      all_pager += 1
    self.all_pager = all_pager

    self.pager_count = pager_count
    self.pager_count_half = int((pager_count - 1) / 2) # 5

    # 保存搜索条件
    import copy
    self.params = copy.deepcopy(request.GET) # {"a":"1","b":"2"}

  # 开始
  @property
  def start(self):
    return (self.current_page_num - 1) * self.per_page_num

  # 结束
  @property
  def end(self):
    return self.current_page_num * self.per_page_num

  # 实现
  def page_html(self):
    # 如果总页码 < 11个:
    if self.all_pager <= self.pager_count:
      pager_start = 1
      pager_end = self.all_pager + 1
    # 总页码 > 11
    else:
      # 当前页如果<=页面上最多显示11/2个页码
      if self.current_page_num <= self.pager_count_half:
        pager_start = 1
        pager_end = self.pager_count + 1
      # 当前页大于5
      else:
        # 页码翻到最后
        if (self.current_page_num + self.pager_count_half) > self.all_pager:

          pager_start = self.all_pager - self.pager_count + 1
          pager_end = self.all_pager + 1

        else:
          pager_start = self.current_page_num - self.pager_count_half
          pager_end = self.current_page_num + self.pager_count_half + 1

    page_html_list = []

    first_page = '<li><a href="?page=%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >首页</a></li>' % (1,)
    page_html_list.append(first_page)

    if self.current_page_num <= 1:
      prev_page = '<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" >上一页</a></li>'
    else:
      prev_page = '<li><a href="?page=%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >上一页</a></li>' % (self.current_page_num - 1,)

    page_html_list.append(prev_page)

    # self.params=copy.deepcopy(request.GET) # {"a":"1","b":"2"}

    for i in range(pager_start, pager_end):

      self.params["page"] = i

      if i == self.current_page_num:
        temp = '<li class="active"><a href="?%s" rel="external nofollow" rel="external nofollow" >%s</a></li>' % (self.params.urlencode(), i)
      else:
        temp = '<li><a href="?%s" rel="external nofollow" rel="external nofollow" >%s</a></li>' % (self.params.urlencode(), i,)
      page_html_list.append(temp)

    if self.current_page_num >= self.all_pager:
      next_page = '<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" >下一页</a></li>'
    else:
      next_page = '<li><a href="?page=%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下一页</a></li>' % (self.current_page_num + 1,)
    page_html_list.append(next_page)
    last_page = '<li><a href="?page=%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >尾页</a></li>' % (self.all_pager,)
    page_html_list.append(last_page)

    return ''.join(page_html_list)

在视图中使用

views.py

# 首先导入包
from myapp.utils.page import Pagination
from myapp.models import User


def index(request):
  # queryset
  user_list = User.objects.all()
  # 总页数
  page_count = user_list.count()
  # 当前页
  current_page_num = request.GET.get("page")
  pagination = Pagination(current_page_num, page_count, request, per_page_num=1)
  # 处理之后的数据
  user_list = user_list[pagination.start:pagination.end]

  content = {
    "user_list": user_list,
    "pagination": pagination,
  }
  return render(request, "user_list.html", content)

页面显示

user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>index</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="external nofollow" >
</head>
<body>
<div class="container">
  <table class="table table-striped">
    <thead>
    <tr>
      <th>name</th>
    </tr>
    </thead>
    <tbody>
    {% for user in user_list %}
      <tr>
        <td>{{ user.name }}</td>
      </tr>
    {% endfor %}
    </tbody>
  </table>
  <!-- bootstrap 样式 -->
  <div class="dataTables_paginate paging_simple_numbers pull-right">
    <ul class="pagination">
      {{ pagination.page_html|safe }}
    </ul>
  </div>
</div>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python支持断点续传的多线程下载示例
Jan 16 Python
Python使用剪切板的方法
Jun 06 Python
JS设计模式之责任链模式实例详解
Feb 03 Python
python看某个模块的版本方法
Oct 16 Python
django主动抛出403异常的方法详解
Jan 04 Python
详解Python读取yaml文件多层菜单
Mar 23 Python
django富文本编辑器的实现示例
Apr 10 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
May 13 Python
如何使用Python 打印各种三角形
Jun 28 Python
python 中值滤波,椒盐去噪,图片增强实例
Dec 18 Python
Python 处理日期时间的Arrow库使用
Aug 18 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
Sep 01 Python
基于python的列表list和集合set操作
Nov 24 #Python
使用Pyhton集合set()实现成果查漏的例子
Nov 24 #Python
Python完全识别验证码自动登录实例详解
Nov 24 #Python
关于Python 常用获取元素 Driver 总结
Nov 24 #Python
pyhton中__pycache__文件夹的产生与作用详解
Nov 24 #Python
使用Python实现画一个中国地图
Nov 23 #Python
用Python画小女孩放风筝的示例
Nov 23 #Python
You might like
twig模板常用语句实例小结
2016/02/04 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
Javascript 遍历对象中的子对象
2009/07/03 Javascript
JavaScript中几种常见排序算法小结
2011/02/22 Javascript
jQuery Tools Dateinput使用介绍
2012/07/14 Javascript
node.js超时timeout详解
2014/11/26 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
谈谈JavaScript异步函数发展历程
2015/09/29 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
详解解决小程序中webview页面多层history返回问题
2019/08/20 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
js实现详情页放大镜效果
2020/10/28 Javascript
[42:50]NB vs VP 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
ptyhon实现sitemap生成示例
2014/03/30 Python
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
详解python中的json的基本使用方法
2016/12/21 Python
python django事务transaction源码分析详解
2017/03/17 Python
基于Python log 的正确打开方式
2018/04/28 Python
Python 迭代,for...in遍历,迭代原理与应用示例
2019/10/12 Python
Django框架安装方法图文详解
2019/11/04 Python
python实现发送带附件的邮件代码分享
2020/09/22 Python
如何用python爬取微博热搜数据并保存
2021/02/20 Python
一款CSS3实现多功能下拉菜单(带分享按)的教程
2014/11/05 HTML / CSS
法律专业个人实习自我鉴定
2013/09/23 职场文书
yy结婚证婚词
2014/01/10 职场文书
公司离职证明范本
2014/01/13 职场文书
公司委托书范本5篇
2014/09/20 职场文书
2015年医务人员医德医风自我评价
2015/03/03 职场文书
小学六年级毕业感言
2015/07/30 职场文书
岗位聘任协议书
2015/09/21 职场文书
教师听课学习心得体会
2016/01/15 职场文书
演讲稿之感恩老师(三篇范文)
2019/09/06 职场文书
Java集成swagger文档组件
2021/06/28 Java/Android