基于 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. for循环性能测试

    项目中遇到需要用for循环dom节点获取每个节点保存的数据,一共有8000多条数据,但是循环加载需要18秒左右才出来. 平时for循环中数据少感觉不出来,现在数据多了就有差别了. 部分代码如下 var ...

  2. 虚拟机安装Windows系统,再安装orcale

    本文出自:http://www.cnblogs.com/2186009311CFF/p/8724441.html 1.创建新虚拟机 2.选择自定义 3.选择workstation 5.x(据安装的系统 ...

  3. BZOJ 1776: [Usaco2010 Hol]cowpol 奶牛政坛 LCA + 树的直径

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

  4. input 的type类型值

    input有很多属性,我们先来说一下最原始的,也就是HTML5之前的 1)text: 定义单行的输入字段,可扎起其中输入文本 2)password:定义密码字段,会显示自符掩码 3)file: 定义输 ...

  5. RedisTemplate访问Redis数据结构(一)——String

    当对String数据结构进行操作时,推荐直接使用spring-data-redis提供的StringRedisTemplate,其配置如下 <bean id="stringRedisT ...

  6. [BZOJ1547]周末晚会:Burnside引理+DP

    分析 Attention!这道题的模数是\(1e8+7\). 注意到循环同构会被认为是同一种方案,我们可以把顺时针旋转每个人的位置作为置换,容易发现这些置换一定会形成一个置换群,于是题目所求的所有合法 ...

  7. C. Anna, Svyatoslav and Maps

    C. Anna, Svyatoslav and Maps 给定一个有向图,给定一条有向路径,求一条顶点最少的路径,使得给定的路径是它的最短路 folyd预处理出任意两点间的最短路,然后判断是否可以缩点 ...

  8. js刷新当前页面的5种方式

    1. reload reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet])   参数: bForceGet, 可选参数, 默认为 false, ...

  9. Fiddler抓取手机Https请求

    下载并安装Fiddler证书生成器 1.打开Fiddler—>Tools—>Telerik Fiddler Options... 2.Connections选项中勾选Allow remot ...

  10. 原生js实现简单的放大镜效果

    前言:相信很多同学在浏览购物网站的时候都会用到过放大镜的功能,这个功能在日常的网站也会经常用到.接下来我们开始实现一下它吧: (1)首先了解一下放大镜效果的html架构:如下图,它由两部分组成. ht ...