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操作列表的常用方法分享
Feb 13 Python
python使用PyGame绘制图像并保存为图片文件的方法
Apr 24 Python
python实现word 2007文档转换为pdf文件
Mar 15 Python
使用python绘制3维正态分布图的方法
Dec 29 Python
python实现图片彩色转化为素描
Jan 15 Python
Python3利用print输出带颜色的彩色字体示例代码
Apr 08 Python
Django在pycharm下修改默认启动端口的方法
Jul 26 Python
Python基于Dlib的人脸识别系统的实现
Feb 26 Python
python 成功引入包但无法正常调用的解决
Mar 09 Python
python中_del_还原数据的方法
Dec 09 Python
python 图像增强算法实现详解
Jan 24 Python
Python列表的深复制和浅复制示例详解
Feb 12 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
Yii2框架中日志的使用方法分析
2017/05/22 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
javascript中length属性的探索
2011/07/31 Javascript
jquery 获取自定义属性(attr和prop)的实现代码
2012/06/27 Javascript
Json序列化和反序列化方法解析
2013/12/19 Javascript
JQuery实现绚丽的横向下拉菜单
2013/12/19 Javascript
关于js数组去重的问题小结
2014/01/24 Javascript
js 判断图片是否加载完以及实现图片的预下载
2014/08/14 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
非jQuery实现照片散落桌子上,单击放大的LightBox效果
2014/11/28 Javascript
jQuery实现html表格动态添加新行的方法
2015/05/28 Javascript
JS实现的3D拖拽翻页效果代码
2015/10/31 Javascript
使用bootstrap插件实现模态框效果
2017/05/10 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
2017/06/20 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
javascript数组拍平方法总结
2018/01/20 Javascript
Vuejs在v-for中,利用index来对第一项添加class的方法
2018/03/03 Javascript
解决JS表单验证只有第一个IF起作用的问题
2018/12/04 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
[45:17]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第三场 1月9日
2021/03/11 DOTA
NumPy.npy与pandas DataFrame的实例讲解
2018/07/09 Python
win8.1安装Python 2.7版环境图文详解
2019/07/01 Python
python中比较两个列表的实例方法
2019/07/04 Python
音频处理 windows10下python三方库librosa安装教程
2020/06/20 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
HTML5 placeholder属性详解
2016/06/22 HTML / CSS
canvas实现俄罗斯方块的方法示例
2018/12/13 HTML / CSS
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
Under Armour安德玛中国官网:美国高端运动科技品牌
2018/03/09 全球购物
新东网科技Java笔试题
2012/07/13 面试题
应付会计岗位职责
2013/12/12 职场文书
2014年人事部工作总结
2014/12/03 职场文书
法学专业求职信范文
2015/03/19 职场文书
2015年教师党员承诺书
2015/04/27 职场文书
2015秋季新学期开学寄语
2015/05/28 职场文书
保护环境建议书作文400字
2015/09/14 职场文书