基于 Python 的自定义分页组件

分页是网页中经常用到的地方,所以将分页功能分出来,作为一个组件可以方便地使用。

分页实际上就是不同的 url ,通过这些 url 获取不同的数据。

业务逻辑简介

  1. 说是组件,其实就是个分页类,能够在试图层对该类进行实例化再传到前端。
  2. 既然是类,初始化时需要的参数就比较重要。
  3. 首页、尾页功能。
  4. 上一页、下一页功能。
  5. 当前页高亮及当前页左右有一定数量的页码。

分页类实现

初始化

初始化传参说明

data_num: 整个数据库的数据数量。

current_page: 当前页码。

url_prefix: url路径前缀。

params: 从前端传过来的键值对。

per_page: 每一页显示的数据数量。

max_show: 页码最多显示几个。

初始化逻辑

一些类的简单属性可以通过初始化传参直接赋值,而复杂的属性则需要根据不同情况做判断后再赋值。

self.data_num = data_num
self.per_page = per_page
self.max_show = max_show
self.url_prefix = url_prefix
# 传过来的参数
self.params = copy.deepcopy(params)
  1. 页码数需要自己算
# 把页码数算出来
self.page_num, more = divmod(data_num, per_page)
if more:
self.page_num += 1
  1. 对当前页码数做判断
try:
self.current_page = int(current_page)
except Exception as e:
self.current_page = 1
# 如果URL传过来的页码数是负数,显示第一页
if self.current_page <= 0:
self.current_page = 1
# 如果URL传过来的页码数超过最大页码数,显示最后一页
elif self.current_page > self.page_num:
self.current_page = self.page_num
  1. 当前页码数左右显示页码
# 页码数的一半
self.half_show = max_show // 2 # 页码最左边显示多少
if self.current_page - self.half_show <= 1:
self.page_start = 1
self.page_end = self.max_show
# 如果右边越界
elif self.current_page + self.half_show >= self.page_num:
self.page_end = self.page_num
self.page_start = self.page_num - self.max_show
else:
self.page_start = self.current_page - self.half_show
# 页码最右边显示
self.page_end = self.current_page + self.half_show

切数据的开始和结束

分页实际上就是在数据库中拿出一定数量的数据显示在前端,我们 用切片来实现取出的数据 ,所以分页类需要有切片的初始位置和结束位置。

我们将两个函数设为静态函数。

@property
def start(self):
# print("current_page", self.current_page)
# 数据从哪开始切
return (self.current_page - 1) * self.per_page @property
def end(self):
# 数据切到哪
return self.current_page * self.per_page

生成页码

以 li 标签为容器,实现页码的前端渲染。在后端对 HTML 标签的进行属性赋值是常用方式。

对于字典,使用 urlencode 函数将其变成在 url 中使用的键值对形式。

加上字典的原因是:搜索或者筛选条件以 GET 请求发送至后端,此时取得的数据应该都是筛选后的,所以在页码中也需要加上此字典。

def page_html(self):
# 生成页码
l = []
# 加一个首页
l.append('<li><a href="{}?page=1">首页</a></li>'.format(self.url_prefix)) # 加一个上一页
if self.current_page == 1:
l.append('<li class="disabled"><a href="#"><<</a></li>')
else:
l.append('<li><a href="{}?page={}"><<</a></li>'.format(self.url_prefix, self.current_page-1)) # 页码
for i in range(self.page_start, self.page_end+1):
self.params["page"] = i
if i == self.current_page:
tmp = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
else:
tmp = '<li><a href="{0}?{1}">{2}</a></li>'.format(self.url_prefix, self.params.urlencode(), i) l.append(tmp) # 加一个下一页
if self.current_page == self.page_num:
l.append('<li class="disabled"><a href="#">>></a></li>')
else:
l.append('<li><a href="{}?page={}">>></a></li>'.format(self.url_prefix, self.current_page + 1)) # 加一个尾页
l.append('<li><a href="{}?page={}">尾页</a></li>'.format(self.url_prefix, self.page_num)) return "".join(l)

视图函数的使用

在视图函数中,需要从 GET 中获取分页类初始化所用的参数并实例化一个类。

将分页实例对象和通过分页切片获取的数据传到前端。

def index(request):
current_page = request.GET.get("page", 1)
all_count = Book.objects.all().count()
base_url = request.path pagination = Pagination(all_count, current_page, base_url, request.GET, per_page=1, max_show=3) book_list = Book.objects.all()[pagination.start : pagination.end] return render(request, "index.html", locals())

前端的使用

前端的使用更为简单,只需要在放置页码的位置引入分页实例对象的页码函数即可。

<body>

<ul>
{% for book in book_list %}
<li>{{ book.title }}</li>
{% endfor %} </ul> <nav>
<ul class="pagination">
{{ pagination.page_html | safe }}
</ul>
</nav>
</body>

GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/s9day90/page_demo

基于 Python 的自定义分页组件的更多相关文章

  1. Python自定义分页组件

    为了防止XSS即跨站脚本攻击,需要加上 safe # 路由 from django.conf.urls import url from django.contrib import admin from ...

  2. 基于vue2.0的分页组件开发

    今天安排的任务是写基于vue2.0的分页组件,好吧,我一开始是觉得超级简单的,但是越写越写不出来,写的最后乱七八糟的都不知道下句该写什么了,所以重新捋了思路,小结一下- 首先写组件需要考虑: 要从父组 ...

  3. 基于jQuery封装的分页组件

    前言: 由于项目需要实现分页效果,上jQuery插件库找了下,但是木有找到自己想要的效果,于是自己封装了个分页组件. 思路: 主要是初始化时基于原型建立的分页模板然后绑定动态事件并实现刷新DOM的分页 ...

  4. 数据分析:基于Python的自定义文件格式转换系统

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  5. Django框架---- 自定义分页组件

    分页的实现与使用 class Pagination(object): """ 自定义分页 """ def __init__(self,cur ...

  6. Angular4.+ ngx-bootstrap Pagination 自定义分页组件

    Angular4 随笔(二)  ——自定义分页组件 1.简介 本组件主要是实现了分页组件显示功能,通过使用 ngx-bootstrap Pagination分页组件实现. 基本逻辑: 1.创建一个分页 ...

  7. 基于 bootstrap 的 vue 分页组件

    申手党点这里下载示例 基于 bootstrap 的 vue 分页组件,我想会有那么一部分同学,在使用Vue的时候不使用单文件组件,因为不架设 NodeJS 服务端.那么网上流传的 *.vue 的各种分 ...

  8. 基于JQ的自定义弹窗组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. vue 自定义分页组件

    vue2.5自定义分页组件,可设置每页显示条数,带跳转框直接跳转到相应页面 Pagination.vue 效果如下图: all: small(只显示数字和上一页和下一页): html <temp ...

随机推荐

  1. linux运维、架构之路-MySQL备份与恢复(四)

    一.备份方式 ①逻辑备份(文件表示:SQL语句) ②物理备份(数据文件的二进制副本) ③基于快照的备份 ④基于复制的备份 二.备份工具 ①mysqldump:原生自带的逻辑备份工具 ②mysqlbin ...

  2. lua脚本入门

    在网上下载一些工程,里边常常存在.lua .sh .in .cmake .bat等文件 今天专门查了一下相关文件的作用 .sh 通常是linux.unix系统下的脚本文件(文本文件),用于调用默认的s ...

  3. SQL把a表字段数据存到b表字段 update,,insert

    update SYS_Navigation set SYS_Navigation.PARENT_XH = SYS_Power_menu.parent_id,SYS_Navigation.web_tit ...

  4. Bugku 杂项 眼见非实(ISCCCTF)

    眼见非实(ISCCCTF) 下载文件后,用winhex打开 发现文件头为50 4B 03 04说明是一个压缩文件,还可以看到其中有.docx文件 更改文件后缀为 .zip 解压后发现 这个文件用wor ...

  5. R 画散点图

    ggplot(data=df, aes(x=n, y=rt, group=kernel, shape=kernel, colour=kernel)) + geom_point(fill="w ...

  6. ORB an efficient alternative to SIFT or SURF

    AbstractFeature matching is at the base of many computer vision problems, such as object recognition ...

  7. python新动态执行 文件头标识 禁止断言

    1.exec “python语句” 2. 3.禁止断言

  8. ecshop 除去版权信息

    ECSHOP 2.73彻底去版权的方法 前台部分: 1. 去掉头部TITLE “- Powered by ecshop” 后者打开includes/lib_main.php $page_title = ...

  9. js中获取当前系统时间

    使用var myDate = new Date();//获取系统当前时间 获取特定格式的时间: 1 myDate.getYear(); //获取当前年份(2位) 2 myDate.getFullYea ...

  10. C++新旧类型转换小记

    旧式类型转换可应对一切转换,不管合不合理,有没有风险,你让我转我就转给你,后果自负. 新式类型转换比较安全,主要体现在父子类之间的运行时转换 dynamic_cast上,若转换失败则返回空指针,而旧式 ...