zoukankan      html  css  js  c++  java
  • python测试开发django-115.Paginator分页器展示table表格数据

    前言

    django自带的分页器Paginator,可以实现分页

    Paginator 分页器

    paginator模块有3个跟分页相关的类

    • Paginator:分页器对象
    • PageNotAnInteger:页码不是一个整数时引发该异常
    • EmptyPage:页码不在有效范围时(即数据为空)引发该异常

    导入Paginator类,可以看到一些内置属性

    from django.core.paginator import Paginator
    
    class Paginator:
    
        def __init__(self, object_list, per_page, orphans=0,
                     allow_empty_first_page=True):
            self.object_list = object_list
            self._check_object_list_is_ordered()
            self.per_page = int(per_page)
            self.orphans = int(orphans)
            self.allow_empty_first_page = allow_empty_first_page
    

    Paginator 实例化的时候需要传的几个参数

    • object_list 查询到的对象list
    • per_page 每页显示的内容
    • orphans=0, 如果最后一页的数据小于这个值,会合并到上一页
    • allow_empty_first_page=True, 允许首页为空 ,默认为True

    分页器常用的方法

    Paginator类实例化后几个常用的属性和方法

    • p.count 获取数据总量
    • p.num_pages 获取总页数,如:23条数据,每页显示5条,总共5页
    • p.page_range 页面对象可迭代范围
    • p.page(1) 传数字,获取对应页的数据
    MyDjango>python manage.py shell
    >>> from yoyo.models import Teacher
    >>> all = Teacher.objects.all()
    >>> from django.core.paginator import Paginator
    
    # 实例化,每页显示5条数据
    >>> p=Paginator(all,per_page=5)
    
    # 获取全部数据 23条
    >>> p.count
    23
    # 获取总页数,23条数据,每页显示5条,总共5页
    >>> p.num_pages
    5 
    # 页面对象可迭代范围1-5   
    >>> p.page_range
    range(1, 6)
    
    # 获取第一页的数据
    >>>  p.page(1)
    <Page 1 of 5>
    
    # 如果页数不在1-5范围,抛异常:EmptyPage
    >>> p.page(0)
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "E:python36libsite-packagesdjangocorepaginator.py", line 65, in page
        number = self.validate_number(number)
      File "E:python36libsite-packagesdjangocorepaginator.py", line 42, in validate_number
        raise EmptyPage(_('That page number is less than 1'))
    django.core.paginator.EmptyPage: That page number is less than 1
    
    # 如果传入的不是数字类型,会抛异常:PageNotAnInteger
    >>> p.page('a')
    Traceback (most recent call last):
      File "E:python36libsite-packagesdjangocorepaginator.py", line 38, in validate_number
        number = int(number)
    ValueError: invalid literal for int() with base 10: 'a'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "E:python36libsite-packagesdjangocorepaginator.py", line 65, in page
        number = self.validate_number(number)
      File "E:python36libsite-packagesdjangocorepaginator.py", line 40, in validate_number
        raise PageNotAnInteger(_('That page number is not an integer'))
    django.core.paginator.PageNotAnInteger: That page number is not an integer
    

    page()传数字类型后返回一个Page类的实例,可以有以下方法

    • number 返回当前操作的是第几页
    • object_list 当前页的操作元素列表
    • has_next() 判断是否有下一页,返回True或False
    • has_previous() 判断是否有上一页,返回True或False
    • has_other_pages() 如果有上一页或下一页,返回True。
    • previous_page_number() 上一页的页码
    • next_page_number() 下一页的页码
    • start_index() 返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。
      比如,将23个对象的列表分为每页5个对象,第2页的start_index()会返回 6。
    • end_index() 返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。
      比如,将23个对象的列表分为每页5个对象,第二页的end_index() 会返回 10
    >>> page1=p.page(1)
    # 返回当前页的对象
    >>> page1
    <Page 1 of 5>
    >>> page1.number
    1
    >>> page1.has_next()
    True
    >>> page1.has_previous()
    False
    >>> page1.start_index()
    1
    >>> page1.end_index()
    5
    

    bootstrap 分页 pagination

    bootstrap 分页功能可以看菜鸟教程https://www.runoob.com/bootstrap/bootstrap-pagination.html

    <!DOCTYPE html>
    <html>
    <head>
    	<meta charset="utf-8"> 
    	<title>Bootstrap 实例 - 分页的状态</title>
    	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">  
    	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
    
    <ul class="pagination">
    	<li><a href="#">上一页</a></li>
    	<li class="active"><a href="#">1</a></li>
    	<li class="disabled"><a href="#">2</a></li>
    	<li><a href="#">3</a></li>
    	<li><a href="#">4</a></li>
    	<li><a href="#">5</a></li>
    	<li><a href="#">下一页</a></li>
    </ul>
    
    </body>
    </html>
    

    如下图左边是pagination分页代码,右边是实现效果,可以在线调试,非常方便

    django 视图函数

    django 视图函数使用分页器Paginator,根据页面url上的请求参数page来获取当前是第几页。

    from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    def teachersView(request):
        teachers = Teacher.objects.all()
        # 分页,每页5个数据
        pa = Paginator(teachers, per_page=5)
        # 获取页数, 如果无默认返回第一页
        page_num = request.GET.get('page', 1)
        # 判断传入的page_num是不是合法数字类型
        try:
            page_num = int(page_num)
            page_object = pa.get_page(page_num)
        except:
            page_object = pa.get_page(1)
        return render(request, 'teacher.html', locals())
    

    把pa,page_num,page_object三个参数给到模板
    上面代码中的get_page() 方法封装了.page()方法当数字超出page_range页码范围时候的异常处理,大于页码或小于页码都返回最后一页

    def get_page(self, number):
            """
            Return a valid page, even if the page argument isn't a number or isn't
            in range.
            """
            try:
                number = self.validate_number(number)
            except PageNotAnInteger:
                number = 1
            except EmptyPage:
                number = self.num_pages
            return self.page(number)
    

    模板实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<title>Bootstrap 实例 - 分页的状态</title>
    	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="container">
        <h3>分页器加载table表格</h3>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>电话</th>
                </tr>
            </thead>
            <tbody>
                {% for field in page_object %}
                    <tr>
                        <td>{{ field.name }}</td>
                        <td>{{ field.age }}</td>
                        <td>{{ field.tel }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
        <ul class="pagination pull-right" id="pager">
            {#上一页按钮开始#}
            {# 如果当前页有上一页#}
            {% if page_object.has_previous %}
                {#  当前页的上一页按钮正常使用#}
                <li class="previous"><a href="/teachers?page={{ page_object.previous_page_number }}">上一页</a></li>
            {% else %}
                {# 当前页的不存在上一页时,上一页的按钮不可用#}
                <li class="previous disabled"><a href="#">上一页</a></li>
            {% endif %}
            {#上一页按钮结束#}
            {# 页码开始#}
            {% for num in pa.page_range %}
    
                {% if num == page_num %}
                    <li class="active"><a href="/teachers?page={{ num }}">{{ num }}</a></li>
                {% else %}
                    <li><a href="/teachers?page={{ num }}">{{ num }}</a></li>
    
                {% endif %}
            {% endfor %}
            {#页码结束#}
            {# 下一页按钮开始#}
            {% if page_object.has_next %}
                <li class="next"><a href="/teachers?page={{ page_object.next_page_number }}">下一页</a></li>
            {% else %}
                <li class="next disabled"><a href="#">下一页</a></li>
            {% endif %}
            {# 下一页按钮结束#}
        </ul>
    </div>
    
    </body>
    </html>
    

    实现效果图

    当页数比较多的时候,中间可以用省略号显示,实现效果如下

    具体实现方式,参考下一篇https://www.cnblogs.com/yoyoketang/p/15237570.html

  • 相关阅读:
    Form.KeyPreview 属性
    键盘输入、鼠标输入、焦点处理
    KeyDown,KeyPress 和KeyUp
    C#反射实例应用--------获取程序集信息和通过类名创建类实例
    Attribute操作的性能优化方式
    OBjective-C:atomic和nonatomic的区别
    Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:
    Objective-C:三种文件导入的方式比较
    Objective-C:保留计数器思想的详解(对象的保留和所有权的释放)
    Objective-C:深复制(拷贝)
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15236252.html
Copyright © 2011-2022 走看看