分页器
下面都是模板语言的分页器,只适用于模板语言
1 # 分页封装方法 2 class MyPage(object): 3 4 def __init__(self, page_num, total_count, base_url, params, per_page_num=3, max_show=5): 5 """ 6 :param params: 当前页码所携带的url里面的键值对参数 7 :param page_num: 当前页面 8 :param total_count: 数据总个数 9 :param base_url: 分页页码跳转的url 10 :param per_page_num: 每一页显示多少条数据 11 :param max_show: 页面上最多显示多少页码 12 """ 13 # 实例化时传进来的参数 14 # 我们在这里捕捉一下异常,把传进去的参数改成数字类型,否则就返回第一页 15 try: 16 page_num = int(page_num) 17 except Exception as e: 18 page_num = 1 19 if page_num < 1: # 如果我们的当前页码出现负数的时候,这里就直接返回第一页,避免出现负数的情况 20 page_num = 1 21 self.params = params 22 self.page_num = page_num 23 self.total_count = total_count 24 self.base_url = base_url 25 self.per_page_num = per_page_num 26 self.max_show = max_show 27 self.half_show = int((self.max_show-1)/2) 28 total_page_num, more = divmod(total_count, per_page_num) 29 """ 30 我们使用总数据的个数对每页显示的数据个数取余,得到的商是页码数,如果有余数就在商的页码数上加一 31 """ 32 if more: 33 total_page_num += 1 34 self.total_page_num = total_page_num 35 36 import copy 37 params = copy.deepcopy(params) # 这里的QueryDict里面是有内置方法,它存储的是一个字典, 38 # 我们的url里面的参数都在这里面,我们要用它就需要对其进行赋值操作,然后它有一个参数是_mutable默认值False, 39 # 不能修改也不能被赋值,我们需要把params给copy一份,使用deepcopy,然后deepcopy的基础上进行赋值 40 params._mutable = True 41 self.params = params # self.params: {'page':23, 'title': python, 'nid': 3} 42 # 这里就是我们的url里面携带的键值对,都封装到params里面了 43 44 # 首页 45 @property 46 def start(self): 47 return (self.page_num-1)*self.per_page_num 48 49 # 尾页 50 @property 51 def end(self): 52 return self.page_num*self.per_page_num 53 54 def page_html(self): 55 """ 56 返回页面上可以用的一段HTML 57 一段可用的分页页码的HTML 58 :return: 59 """ 60 # 如果总页码数<=最大显示页码数,那么起始页码数分别是什么 61 if self.total_page_num <= self.max_show: 62 page_start = 1 63 page_end = self.total_page_num 64 else: # 如果当前页<=最多显示的页码数的一半,那么起始页码分别是什么 65 """ 66 假设,我们最多显示7个分页,那么第一页就是1,最后一页就是7,但是我们的当前页是2, 67 它往前倒推7/2商3余1,2-3得到当前页的首页-1,就是负数了,所以这个时候需要做限制,让首页等于1, 68 """ 69 if self.page_num <= self.half_show: 70 page_start = 1 71 page_end = self.max_show 72 else: 73 # 如果当前页>=总页码数-最多显示的页码数的一半,那么起始页码分别是什么 74 """ 75 如果我们在第6页,我们的页面最多显示7个页码,而我们的总数据就只能显示8页的话, 76 倒推的6+7/2商3余1,就是(6+3)>8,我们的第9页就是空白页,这个时候就需要加以限制, 77 此时第一页就是8-6+1,也就是从第二页开始,一直到第八页,就刚好是7页,这样就完美了 78 此时最后一页就是数据最多所展示的页码第8页 79 """ 80 if self.page_num >= self.total_page_num - self.half_show: 81 page_start = self.total_page_num - self.max_show + 1 82 page_end = self.total_page_num 83 else: # 最后到这里我们判断了数据所在的页码出现在最前面把负数页码排除了,也判断了数据所在的页码出现最后面把空白页码排除了, 84 # 也判断了总页码数还不够我们所设置的最大页码显示,就剩下最后一种情况了,那就是当前页不在最后也不在最前, 85 # 直接用当前页加上或减去最大显示页的1/2,就得到了起始页面 86 page_start = self.page_num - self.half_show 87 page_end = self.page_num + self.half_show 88 89 # 生成前页码的HTML 90 page_html_list = [] 91 92 # 生成第一页 93 self.params['page'] = 1 94 page_first_tmp = '<li><a href="{}?{}">首页</a><li>'.format(self.base_url, self.params.urlencode(),) 95 page_html_list.append(page_first_tmp) 96 97 # 生成上一页 98 if self.page_num <= 1: 99 page_prev_tmp = '<li class=disabled><a href="#">上一页</a></li>' 100 else: 101 self.params['page'] = self.page_num-1 102 page_prev_tmp = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url, self.params.urlencode(),) 103 104 page_html_list.append(page_prev_tmp) 105 106 # 生成页码中间页数前半截 107 for i in range(page_start, page_end+1): 108 self.params['page'] = i 109 if i == self.page_num: 110 tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url, self.params.urlencode(), i) 111 else: 112 tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url, self.params.urlencode(), i,) 113 114 page_html_list.append(tmp) 115 116 # 生成页码中间页数后半截 117 if self.page_num + 1 > self.total_page_num: 118 page_next_tmp = '<li class="disabled"><a href="#">下一页</a></li>' 119 else: 120 self.params['page'] = self.page_num+1 121 page_next_tmp = '<li><a href="{}?{}">下一页</a></li>'.format(self.base_url, self.params.urlencode(),) 122 123 page_html_list.append(page_next_tmp) 124 125 # 生成最后一页 126 self.params['page'] = self.total_page_num 127 page_last_tmp = '<li><a href="{}?{}">尾页</a></li>'.format(self.base_url, self.params.urlencode(),) 128 page_html_list.append(page_last_tmp) 129 130 return "".join(page_html_list)
1 # 分页封装方法 2 class MyPage(object): 3 4 def __init__(self, page_num, total_count, base_url, per_page_num=3, max_show=5): 5 """ 6 :param page_num: 当前页面 7 :param total_count: 数据总个数 8 :param base_url: 分页页码跳转的url 9 :param per_page_num: 每一页显示多少条数据 10 :param max_show: 页面上最多显示多少页码 11 """ 12 # 实例化时传进来的参数 13 # 我们在这里捕捉一下异常,把传进去的参数改成数字类型,否则就返回第一页 14 try: 15 page_num = int(page_num) 16 except Exception as e: 17 page_num = 1 18 if page_num < 1: # 如果我们的当前页码出现负数的时候,这里就直接返回第一页,避免出现负数的情况 19 page_num = 1 20 self.page_num = page_num 21 self.total_count = total_count 22 self.base_url = base_url 23 self.per_page_num = per_page_num 24 self.max_show = max_show 25 self.half_show = int((self.max_show-1)/2) 26 total_page_num, more = divmod(total_count, per_page_num) 27 """ 28 我们使用总数据的个数对每页显示的数据个数取余,得到的商是页码数,如果有余数就在商的页码数上加一 29 """ 30 if more: 31 total_page_num += 1 32 self.total_page_num = total_page_num 33 34 # 首页 35 @property 36 def start(self): 37 return (self.page_num-1)*self.per_page_num 38 39 # 尾页 40 @property 41 def end(self): 42 return self.page_num*self.per_page_num 43 44 def page_html(self): 45 """ 46 返回页面上可以用的一段HTML 47 一段可用的分页页码的HTML 48 :return: 49 """ 50 # 如果总页码数<=最大显示页码数,那么起始页码数分别是什么 51 if self.total_page_num <= self.max_show: 52 page_start = 1 53 page_end = self.total_page_num 54 else: # 如果当前页<=最多显示的页码数的一半,那么起始页码分别是什么 55 """ 56 假设,我们最多显示7个分页,那么第一页就是1,最后一页就是7,但是我们的当前页是2, 57 它往前倒推7/2商3余1,2-3得到当前页的首页-1,就是负数了,所以这个时候需要做限制,让首页等于1, 58 """ 59 if self.page_num <= self.half_show: 60 page_start = 1 61 page_end = self.max_show 62 else: 63 # 如果当前页>=总页码数-最多显示的页码数的一半,那么起始页码分别是什么 64 """ 65 如果我们在第6页,我们的页面最多显示7个页码,而我们的总数据就只能显示8页的话, 66 倒推的6+7/2商3余1,就是(6+3)>8,我们的第9页就是空白页,这个时候就需要加以限制, 67 此时第一页就是8-6+1,也就是从第二页开始,一直到第八页,就刚好是7页,这样就完美了 68 此时最后一页就是数据最多所展示的页码第8页 69 """ 70 if self.page_num >= self.total_page_num - self.half_show: 71 page_start = self.total_page_num - self.max_show + 1 72 page_end = self.total_page_num 73 else: # 最后到这里我们判断了数据所在的页码出现在最前面把负数页码排除了,也判断了数据所在的页码出现最后面把空白页码排除了, 74 # 也判断了总页码数还不够我们所设置的最大页码显示,就剩下最后一种情况了,那就是当前页不在最后也不在最前, 75 # 直接用当前页加上或减去最大显示页的1/2,就得到了起始页面 76 page_start = self.page_num - self.half_show 77 page_end = self.page_num + self.half_show 78 79 # 生成前页码的HTML 80 page_html_list = [] 81 page_first_tmp = '<li><a href="{}?page=1">首页</a><li>'.format(self.base_url,) 82 page_html_list.append(page_first_tmp) 83 84 # 生成上一页 85 if self.page_num <= 1: 86 page_prev_tmp = '<li class=disabled><a href="#">上一页</a></li>' 87 else: 88 page_prev_tmp = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url, self.page_num-1,) 89 90 page_html_list.append(page_prev_tmp) 91 92 # 生成页码中间页数前半截 93 for i in range(page_start, page_end+1): 94 if i == self.page_num: 95 tmp = '<li class="active"><a href="{0}?{1}">{1}</a></li>'.format(self.base_url, i) 96 else: 97 tmp = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i,) 98 99 page_html_list.append(tmp) 100 101 # 生成页码中间页数后半截 102 if self.page_num + 1 > self.total_page_num: 103 page_next_tmp = '<li class="disabled"><a href="#">下一页</a></li>' 104 else: 105 page_next_tmp = '<li><a href="{0}?page={1}">下一页</a></li>'.format(self.base_url, self.page_num+1,) 106 107 page_html_list.append(page_next_tmp) 108 109 # 生成最后一页 110 page_last_tmp = '<li><a href="{0}?page={1}">尾页</a></li>'.format(self.base_url, self.total_page_num,) 111 page_html_list.append(page_last_tmp) 112 113 return "".join(page_html_list)
自己写的,更容易理解的版本
代码不如上面的版本简洁,但是逻辑更顺畅,更容易理解。
class TryPagination: def __init__(self, current_page, total_data_length, base_url, max_page_length, per_page): self.total_data_length = total_data_length self.base_url = base_url self.max_page_length = max_page_length self.per_page = per_page self.current_page = int(current_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): # get the first page page_count, plus_page = divmod(self.total_data_length, self.per_page) if plus_page: page_count += 1 total_html_li = [] if page_count <= self.max_page_length: for i in range(1, page_count+1): show_index_page = "<li><a href='{0}?page={1}'>{1}</a></li>" \ .format(self.base_url, i) total_html_li.append(show_index_page) else: half_max_length = self.max_page_length // 2 # todo not yet range_max = self.max_page_length + 1 if self.current_page - half_max_length <= 1: for i in range(1, range_max): show_index_page = "<li><a href='{0}?page={1}'>{1}</a></li>" \ .format(self.base_url, i) total_html_li.append(show_index_page) else: if self.current_page >= page_count - half_max_length: for i in range(1, range_max): show_index_page = "<li><a href='{0}?page={1}'>{1}</a></li>" \ .format(self.base_url, page_count-self.max_page_length+i) total_html_li.append(show_index_page) else: for i in range( self.current_page-half_max_length, self.current_page+half_max_length+1 ): if i == self.current_page: show_index_page = "<li><a href='{0}?page={1}'>{1}</a></li>" \ .format(self.base_url, self.current_page) else: show_index_page = "<li><a href='{0}?page={1}'>{1}</a></li>" \ .format(self.base_url, i) total_html_li.append(show_index_page) first_page = "<li><a href='{}?page=1'>首页</a></li>".format(self.base_url) last_count = self.current_page-1 if last_count < 1: last_page = "<li class=disable><a href='#'>上一页</a></li>" else: last_page = "<li><a href='{}?page={}'>上一页</a></li>".format( self.base_url, last_count) next_count = self.current_page + 1 if next_count > page_count: next_page = "<li class=disable><a href='#'>下一页</a></li>" else: next_page = "<li><a href='{}?page={}'>下一页</a></li>".format( self.base_url, next_count ) total_html_li.append(next_page) total_html_li.insert(0, first_page) total_html_li.insert(1, last_page) end_page = "<li><a href='{}?page={}'>尾页</a></li>".format( self.base_url, page_count ) total_html_li.append(end_page) return "".join(total_html_li)
前端HTML模板:
1 <nav aria-label="Page navigation"> 2 <ul class="pagination"> 3 {{ sl.pagination.page_html|safe }} 4 </ul> 5 </nav>