分页器两种版本,普通版和进阶版

  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>
原文地址:https://www.cnblogs.com/2012-dream/p/8584994.html