zoukankan      html  css  js  c++  java
  • 简单的分页器实现

    简单的分页功能

    urls.py

    urlpatterns = [
        url(r'^page/', views.page,name='page'),
    ]

    views.py

    users = [{"name": f"alex{i}", "pwd": "dsb"} for i in range(1, 355)]
    
    def page(request):
        user_list = users
        try:
            page = int(request.GET.get('page', 1))
            if page <= 0:
                page = 1
        except Exception:
            page = 1
    
        """
        索引切片
        page   起始   终止
        1       0     10
        2       10    20
        3       20    30
        """
        # 每页展示的数据
        per_num = 10
        # 数据切片起始值
        start = (page - 1) * per_num
        # 数据切片终止值
        end = page * per_num
        # 总数据条数
        page_count = len(user_list)
        # 总页码数
        sum_page, more = divmod(page_count, per_num)
        if more:
            sum_page += 1
        # 前端循环的a标签的值
        num = [i for i in range(1, sum_page + 1)]
        user_list = user_list[start:end]
        return render(request, 'page.html', locals())

    html.py(bootstrap样式中的分页组件)

       <div class="form-group col-sm-7">
            <table class="table table-hover table-bordered">
                <thead>
                <tr>
                    <th>name</th>
                    <th>pwd</th>
                </tr>
                </thead>
                <tbody>
                {% for user in user_list %}
                    <tr>
                        <td>{{ user.name }}</td>
                        <td>{{ user.pwd }}</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    
        <div class="pull-left form-group col-sm-7">
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    <li>
                        <a href="#" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>
                    {% for n in num %}
                        <li><a href="{% url 'page' %}?page={{ n }}">{{ n }}</a></li>
                    {% endfor %}
                    <li>
                        <a href="#" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                </ul>
            </nav>
        </div>

    效果:简单的分页完成

     上面功能中展示了数据的所有的页码,接下来我们将会对页码的展示进行升级,如:每页展示十个页码

    页码数量限制

    url与html文件不变

    views.py

    users = [{"name": f"alex{i}", "pwd": "dsb"} for i in range(1, 301)]
    
    def page(request):
        user_list = users
        try:
            page = int(request.GET.get('page', 1))
            if page <= 0:
                page = 1
        except Exception:
            page = 1
    
        """
        索引切片
        page   起始   终止
        1       0     10
        2       10    20
        3       20    30
        """
        # 每页展示的数据
        per_num = 10
        # 数据切片起始值
        start = (page - 1) * per_num
        # 数据切片终止值
        end = page * per_num
        # 总数据条数
        page_count = len(user_list)
        # 总页码数
        sum_page, more = divmod(page_count, per_num)
        if more:
            sum_page += 1
        # 前端循环的a标签的值
        num = [i for i in range(1, sum_page + 1)]
    
        # 页码限制
        # 页面最大显示页码
        max_show = 10
        # 页码的切片的起始值
        page_start = 0
        # 页码切片的终止值
        page_end = max_show
        # 页码的偏移量
        half_page = max_show // 2
        if page < max_show:
            """
            如果page在第一页,什么都不做,即page_start=0,page_end=max_show
            """
            pass
        if page > sum_page:
            """
            如果page参数大于总页码数,跳转到最后一页,针对于url上面手动输入page参数
            """
            # 终止值为最后一页
            page_end = sum_page
            # 起始值向前便宜half_page
            page_start = page_end - half_page
            # 数据部分也需要设定,不然显示为空
            start = (sum_page - 1) * per_num
            end = sum_page * per_num
        else:
            """
            page当前页码即不在第一页,也不在最后一页(或超过最后一页),起始值向前偏移half_page,向后偏移half_page
            """
            page_start = page - half_page
            page_end = page + half_page
        
        # 当总页码数小于每页最大展示页码数量时,无论在那一页都展示全部的页码(针对数据少,page处于max_show与sum_page之间时的bug)
        if sum_page < max_show:
            page_start = 0
            page_end = sum_page
            
        num = num[page_start:page_end]
        user_list = user_list[start:end]
        return render(request, 'page.html', locals())

    当前页选中

    bootstrap中active类选择器是激活的样式,在前端判断后台接收到的page登不等于前端的页码,等于则添加激活样式。

    html文件

    ......
     <div class="pull-left form-group col-sm-7">
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    <li>
                        <a href="#" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>
                    {% for n in num %}
                        <li class="{% if page == n %}active{% endif %}"><a href="{% url 'page' %}?page={{ n }}">{{ n }}</a>  {# 主要操作在这里#}
                        </li>
                    {% endfor %}
                    <li>
                        <a href="#" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                </ul>
            </nav>
        </div>
    ......

    正常情况下,激活样式是完成的,但这里有个bug就是当手动在url地址中输入大于总页码的page时就没有激活样式了,所以,我们需要在views文件中针对性的将page修改一下,如下:

    ......
        if page > sum_page:
            """
            如果page参数大于总页数,跳转到最后一页,针对于url上面手动输入page参数
            """
            # 终止值为最后一页
            page_end = sum_page
            # 起始值向前便宜half_page
            page_start = page_end - half_page
            # 数据部分也需要设定,不然显示为空
            start = (sum_page - 1) * per_num
            end = sum_page * per_num
            # 当page大于总页码时,让page等于最大的页码,为了给最后一页添加激活样式  # 主要操作在这里,原理是:因为当用户手动输入的页码大于总页码时,后台获取的数据与前端的必然不同,因此,我们在这里手动将page设置为总页码,即可。
            page = sum_page
    ......

    效果如图:

     激活样式添加完成

    后台进行页码样式的编写及上下页设置

    这里主要在后台生成html代码(页码相关的html代码,包括样式的激活,上下页等,都在后台生成,前端只需要调用即可)

    views.py

    # -*- coding: utf-8 -*-
    # __author__ = "maple"
    
    
    users = [{"name": f"alex{i}", "pwd": "dsb"} for i in range(1, 301)]
    
    def page(request):
        user_list = users
        try:
            page = int(request.GET.get('page', 1))
            if page <= 0:
                page = 1
        except Exception:
            page = 1
    
        """
        索引切片
        page   起始   终止
          0     10
          10    20
          20    30
        """
        # 每页展示的数据
        per_num = 3
        # 数据切片起始值
        start = (page - 1) * per_num
        # 数据切片终止值
        end = page * per_num
        # 总数据条数
        page_count = len(user_list)
        # 总页码数
        sum_page, more = divmod(page_count, per_num)
        if more:
            sum_page += 1
        # 前端循环的a标签的值
        num = [i for i in range(1, sum_page + 1)]
    
        # 页码限制
        # 页面最大显示页码
        max_show = 6
        # 页码的切片的起始值
        page_start = 0
        # 页码切片的终止值
        page_end = max_show
        # 页码的偏移量
        half_page = max_show // 2
    
        if page < max_show:
            """
            如果page在第一页,什么都不做,即page_start=0,page_end=max_show
            """
            pass
        if page > sum_page:
            """
            如果page参数大于总页码数,跳转到最后一页,针对于url上面手动输入page参数
            """
            # 终止值为最后一页
            page_end = sum_page
            # 起始值向前偏移half_page
            page_start = page_end - half_page
            # 数据部分也需要设定,不然显示为空
            start = (sum_page - 1) * per_num
            end = sum_page * per_num
            # 当page大于总页码时,让page等于最大的页码,为了给最后一页添加激活样式
            page = sum_page
        else:
            """
            page当前页码即不在第一页,也不在最后一页(或超过最后一页),起始值向前偏移half_page,向后偏移half_page
            """
            page_start = page - half_page
            page_end = page + half_page
    
        # 当总页码数小于每页最大展示页码数量时,无论在那一页都展示全部的页码(针对数据少,page处于max_show与sum_page之间时的bug)
        if sum_page < max_show:
            page_start = 0
            page_end = sum_page
    
        num = num[page_start:page_end]
    
        html_list = []
        # 页码样式的头
        html_list.append(
            '<div class="pull-left form-group col-sm-7"><nav aria-label="Page navigation"><ul class="pagination">')
        # 当当前页为1时,添加上一页禁用样式disabled
        if page == 1:
            html_list.append(
                '<li class="disabled"><a aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>')
        else:
            html_list.append(
                '<li ><a href="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                    page - 1))
    
        for n in num:
            if page == n:
                html_list.append('<li class="active"><a>{}</a></li>'.format(n))
            else:
                html_list.append('<li><a href="?page={}">{}</a></li>'.format(n, n))
    
        # 当前页为最后一页时,添加下一页禁用样式disabled
        if page == sum_page:
            html_list.append(
                '<li class="disabled"><a  aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>')
        else:
            html_list.append(
                '<li><a href="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                    page + 1))
    
        # 页码样式的尾
        html_list.append('</ul></nav></div>')
    
        # 将列表中的html代码拼接起来
        html_list = "".join(html_list)
    
        user_list = user_list[start:end]
        return render(request, 'page.html', locals())
     
    View Code

    html.py(附带所有的关于关于页码的样式)

     {{ html_list|safe }}

    小工具:跳转

    html页面

        {{ html_list|safe }}
     # form表单不写method默认为get请求,且get请求会将input提交的值以url参数的形式保存并提交到后台
        <form action="">
            <input type="text" name="page">
            <button>跳转</button>
        </form>

    至此,简单的分页功能就已经完成了,但我们以后开发项目必然要用到分页功能,我们要如何使用自己开发的分页功能呢?在写一遍?不,我们将它封装成类,在使用的时候进行调用即可。

    封装成类

    class Pagination(object):
        def __init__(self, page, page_count, per_num=10, max_show=10):
            """
            :param page:前端传入的页码
            :param page_count: 分页的数据总条数
            :param per_num: 每页显示的数据条数
            :param max_show: 每页显示的最大页码数
            """
            self.page = page
            self.page_count = page_count
            self.per_num = per_num
            self.max_show = max_show
    
            try:
                self.page = int(self.page)
                if self.page <= 0:
                    self.page = 1
            except Exception:
                self.page = 1
    
            """
            索引切片
            page   起始   终止
          0     10
          10    20
          20    30
            """
            # 数据切片起始值
            self.start = (self.page - 1) * self.per_num
            # 数据切片终止值
            self.end = self.page * self.per_num
            # 总页码数
            self.sum_page, more = divmod(self.page_count, self.per_num)
            if more:
                self.sum_page += 1
            # 前端循环的a标签的值
            self.num = [i for i in range(1, self.sum_page + 1)]
    
            # 页码限制
            # 页码的切片的起始值
            self.page_start = 0
            # 页码切片的终止值
            self.page_end = self.max_show
            # 页码的偏移量
            half_page = self.max_show // 2
    
            if self.page < self.max_show:
                """
                如果page在第一页,什么都不做,即page_start=0,page_end=max_show
                """
                pass
    
            if self.page > self.sum_page:
                """
                如果page参数大于总页码数,跳转到最后一页,针对于url上面手动输入page参数
                """
                # 终止值为最后一页
                self.page_end = self.sum_page
                # 起始值向前偏移half_page
                self.page_start = self.page_end - half_page
                # 数据部分也需要设定,不然显示为空
                self.start = (self.sum_page - 1) * self.per_num
                self.end = self.sum_page * self.per_num
                # 当page大于总页码时,让page等于最大的页码,为了给最后一页添加激活样式
                self.page = self.sum_page
    
            else:
                """
                page当前页码即不在第一页,也不在最后一页(或超过最后一页),起始值向前偏移half_page,向后偏移half_page
                """
                self.page_start = self.page - half_page
                self.page_end = self.page + half_page
    
            # 当总页码数小于每页最大展示页码数量时,无论在那一页都展示全部的页码
            if self.max_show > self.sum_page:
                self.page_start = 0
                self.page_end = self.sum_page
            # 当传入的总数据量小于等于0时(主要是等于零),会报错,通过下面的判断来解决这个问题
            if page_count <= 0:
                self.start = 0
                self.end = 0
    
        def page_html(self):
            num = self.num[self.page_start:self.page_end]
            html_list = []
            # 页码样式的头
            html_list.append(
                '<div class="pull-left form-group col-sm-7" style="padding-left:0"><nav  aria-label="Page navigation"><ul class="pagination">')
            # 当前页为1时,添加上一页禁用样式disabled
            if self.page == 1:
                html_list.append(
                    '<li class="disabled"><a aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>')
            else:
                html_list.append(
                    '<li ><a href="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                        self.page - 1))
            for n in num:
                if self.page == n:
                    html_list.append('<li class="active"><a>{}</a></li>'.format(n))
                else:
                    html_list.append('<li><a href="?page={}">{}</a></li>'.format(n, n))
    
            # 当前页为最后一页时,添加下一页禁用样式disabled
            if self.page == self.sum_page:
                html_list.append(
                    '<li class="disabled"><a aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>')
            else:
                html_list.append(
                    '<li><a href="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                        self.page + 1))
            # 页码样式的尾
            html_list.append('</ul></nav></div>')
            # 将列表中的html代码拼接起来
            html_list = "".join(html_list)
            return html_list
    View Code

    使用自定义分页器类

    views.py

    users = [{"name": f"alex{i}", "pwd": "dsb"} for i in range(1, 355)]
    
    from utils import pagination
    def page(request):
        user_list = users
        page = request.GET.get('page')
        pat_obj = pagination.Pagination(page, len(user_list)) # 实例化一个分页器对象
        user_list = user_list[pat_obj.start:pat_obj.end] # 进行数据的切片操作
        return render(request, 'page.html', locals())

    page.html

        <div class="form-group col-sm-7">
            <table class="table table-hover table-bordered">
                <thead>
                <tr>
                    <th>name</th>
                    <th>pwd</th>
                </tr>
                </thead>
                <tbody>
                {% for user in user_list %}
                    <tr>
                        <td>{{ user.name }}</td>
                        <td>{{ user.pwd }}</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
        {{ pat_obj.page_html|safe }}  {# 通过分页器对象调用page_html方法 #}

    注:分页器中引入的是bootstrap框架的样式,使用前需先在模板中引入bootstrap

    分页器终极版

    分页器:

    # -*- coding: utf-8 -*-
    # __author__ = "maple"
    from django.http.request import QueryDict
    
    
    class Pagination(object):
        def __init__(self, page, page_count, qd=None, per_num=10, max_show=10):
            """
            :param page:前端传入的页码
            :param page_count: 分页的数据总条数
            :param per_num: 每页显示的数据条数
            :param max_show: 每页显示的最大页码数
            """
            self.page = page
            self.page_count = page_count
            self.per_num = per_num
            self.max_show = max_show
            self.qd = qd
            if not qd:
                qd = QueryDict(mutable=True)
                self.qd = qd
    
            try:
                self.page = int(self.page)
                if self.page <= 0:
                    self.page = 1
            except Exception:
                self.page = 1
    
            """
            索引切片
            page   起始   终止
            1       0     10
            2       10    20
            3       20    30
            """
            # 数据切片起始值
            self.start = (self.page - 1) * self.per_num
            # 数据切片终止值
            self.end = self.page * self.per_num
            # 总页码数
            self.sum_page, more = divmod(self.page_count, self.per_num)
            if more:
                self.sum_page += 1
            # 前端循环的a标签的值
            self.num = [i for i in range(1, self.sum_page + 1)]
    
            # 页码限制
            # 页码的切片的起始值
            self.page_start = 0
            # 页码切片的终止值
            self.page_end = self.max_show
            # 页码的偏移量
            half_page = self.max_show // 2
    
            if self.page < self.max_show:
                """
                如果page在第一页,什么都不做,即page_start=0,page_end=max_show
                """
                pass
    
            if self.page > self.sum_page:
                """
                如果page参数大于总页码数,跳转到最后一页,针对于url上面手动输入page参数
                """
                # 终止值为最后一页
                self.page_end = self.sum_page
                # 起始值向前偏移half_page
                self.page_start = self.page_end - half_page
                # 数据部分也需要设定,不然显示为空
                self.start = (self.sum_page - 1) * self.per_num
                self.end = self.sum_page * self.per_num
                # 当page大于总页码时,让page等于最大的页码,为了给最后一页添加激活样式
                self.page = self.sum_page
    
            else:
                """
                page当前页码即不在第一页,也不在最后一页(或超过最后一页),起始值向前偏移half_page,向后偏移half_page
                """
                self.page_start = self.page - half_page
                self.page_end = self.page + half_page
    
            # 当总页码数小于每页最大展示页码数量时,无论在那一页都展示全部的页码
            if self.max_show > self.sum_page:
                self.page_start = 0
                self.page_end = self.sum_page
            # 当传入的总数据量小于等于0时(主要是等于零),会报错,通过下面的判断来解决这个问题
            if page_count <= 0:
                self.start = 0
                self.end = 0
    
        def page_html(self):
            num = self.num[self.page_start:self.page_end]
            html_list = []
            # 页码样式的头
            html_list.append(
                '<div class="pull-left form-group col-sm-7" style="padding-left:0"><nav  aria-label="Page navigation"><ul class="pagination">')
            # 当前页为1时,添加上一页禁用样式disabled
            if self.page == 1:
                self.qd['page'] = 1
                html_list.append(
                    '<li class="disabled"><a href="?{}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                        self.qd.urlencode()))
            else:
                self.qd['page'] = self.page -1
                html_list.append(
                    '<li ><a href="?{}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                        self.qd.urlencode()))
            for n in num:
                self.qd['page'] = n
                if self.page == n:
                    html_list.append('<li class="active"><a>{}</a></li>'.format(n))
                else:
                    html_list.append('<li><a href="?{}">{}</a></li>'.format(self.qd.urlencode(), n))
    
            # 当前页为最后一页时,添加下一页禁用样式disabled
            if self.page == self.sum_page:
                self.qd['page'] = self.sum_page
                html_list.append(
                    '<li class="disabled"><a href="?{}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                        self.qd.urlencode()))
            else:
                self.qd['page'] = self.page + 1
                html_list.append(
                    '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                        self.qd.urlencode()))
            # 页码样式的尾
            html_list.append('</ul></nav></div>')
            # 将列表中的html代码拼接起来
            html_list = "".join(html_list)
            return html_list
    View Code

    使用:

    from utils import pagination # 导入自定义分页器
    page = request.GET.get('page', 1) #获取当前页码参数
    pag_obj = pagination.Pagination(page=page, page_count=customer_obj.count(),qd=request.GET.copy(), per_num=3, max_show=10) #实例化分页器对象
    customer_obj = customer_obj[pag_obj.start:pag_obj.end] # 对queryset对象进行分页
  • 相关阅读:
    【原】戏说Java
    git分支branch合并到主分支master
    环境搭建
    zookeeper简单实战
    zookeeper介绍
    临时表与中间表
    避免活跃性
    sss
    sss
    sss
  • 原文地址:https://www.cnblogs.com/kindvampire/p/12342484.html
Copyright © 2011-2022 走看看