zoukankan      html  css  js  c++  java
  • django-分页器

    #######django-分页器########
    问题的引出:在模板页面渲染时,比如我们渲染的是书籍的一些信息,假如就只有10,20本书,
              完全可以渲染出来(意思的渲染出来,不会影响页面的美观),万一是一个很多的图书系统,
              里面的书籍几千本,上万本,你在一个页面渲染出来(不知道一个页面行不行),肯定是不
              好看的,所以这时候必须要有分页器了。
    
    那怎么去使用分页器呢?
    from django.core.paginator import Paginator
    
    paginator = Paginator(object_list,per_page)
    # 解释下这里的参数吧,其实一看就能明白个大概
    # object_list:对象列表,也是就一个列表里装多个对象元素
    # per_page:就是一页显示多少条记录
    paginator对象下有很多方法,说实话,我也记不住,但是在写程序的时候,你可以通过.来看
    他下面的一系列的方法,通过方法名字,你可以大概知道是什么意思。
    
    # num_pages  看名字就大概知道这是显示该对象有多少页,看源码,它返回的是一个int类型的数字
    # 它是一个对象的方法,通过装饰器伪装成对象属性
    page_num = paginator.num_pages
    
    # count 这个单词肯定会吧,在这里显示的是object_list中元素的个数,也是一个方法看它的源码,
    # 大概就是这样出来,假如是个列表的话,就调用列表下的count方法,不是的话,就直接用len()方法了,
    count = paginator.count
    
    # page_range 这个和range差不多
    PageRange = paginator.page_range
    
    # page  传一个数字,假如你想取到第五页,就传5进去,他会返回一个page对象,这个对象里是当前页的一些对象
    # 返回的page对象下面也有方法
    page_obj = paginator.page(1)
    
    # has_next()它的返回值是一个布尔类型,大概意思就是:是否有下一页
    page_obj.has_next()
    
    # has_next()它的返回值是一个布尔类型,大概意思就是:是否有上一页
    page_obj.has_previous()
    
    # previous_page_number() 它的返回值是一个int类型,上一页的页码数
    page_obj.previous_page_number()
    
    # next_page_number() 它的返回值是一个int类型,下一页的页码数
    page_obj.next_page_number()
    
    
    ####简单些写一个分页器的效果(前提我数据库中有100条数据)
        不考虑代码的健壮性问题
    models文件:
        class Book(models.Model)
            name = models.CharField(max_length=32)
    
    views文件:
        def index(request):
            books = models.Book.objects.all()
            paginator = Paginator(books,10)
            get_num = request.GET.get('page')
            page_obj = paginator.page(int(get_num))
            return render(request,'index.html',local())
    
    index.html文件:
        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>书名</th>
                </tr>
            </thead>
            <tbody>
                {% for book in page_obj %}
                    <tr>
                        <td>{{book.id}}</td>
                        <td>{{book.name}}</td>
                    </tr>
                {%endfor%}
            </tbody>
        </table>
    
    上面就是一个简单的分页效果,你可以通过127.0.0.1:8000/index?page=2,给page传值访问到想要的页面
    想要在下面写一个分页的按钮,比如上一页,第几页什么的,你前端好的话可以写写,我前端太差,就说说思路
    我们是不是可以通过paginator这个对象,拿到有多少页(num_pages这个方法对吧),然后就是for循环的事了,
    a标签对应的url记得相对应哟。上面的代码完全没考虑到健壮性,会有bug的。
    
    bug:
       1、假如输入的url为127.0.0.1:8000/index?page=1111,很显然,我100条数据,每页10条,就10页对吧
          显然1111超过了我的范围,是负数也是不符合吧,这是一个点会出bug,
       2、还有我的url为127.0.0.1:8000/index?page=sadas,很显然这不是一个int类型,我视图函数中直接用int
          转换也会出错。
       3、最后开始我只有100条数据,万一我有一万条数据,那么就是1000页,那我在前端不就是有1000个页码数嘛?
    
    下面是改进版(样式不会调,我就用bootstrap):
    
    views文件:
        def index(request):
            books = models.Book.objects.all()
            paginator = Paginator(books, 5)
            try:
                # 从get请求中取到浏览器请求的页码数get_num,假如不能转成整型,就跳转到第一页
                get_num = request.GET.get('page')
                get_num = int(get_num)
            except Exception as e:
                get_num = 1
            # 这里分页器遵循前五页,后五页,和当前页
            if paginator.num_pages > 11:
                if get_num-5 < 1:
                    PageRange = range(1,12)
                elif get_num+5 > paginator.num_pages:
                    PageRange = range(paginator.num_pages-11,paginator.num_pages+1)
                else:
                    PageRange = range(get_num-5,get_num+6)
            else:
                PageRange = paginator.page_range
            try:
                # 这里万一浏览器请求的页码数get_num大于paginator.num_pages,就会报错,我捕捉该异常
                page_obj = paginator.page(get_num)
            except Exception as e:
                get_num = 1
                page_obj = paginator.page(get_num)
            return render(request, 'index.html', locals())
    
    index.html文件:
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <title>图书列表</title>
    </head>
    <body>
    <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-8">
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>序号</th>
                    <th>书名</th>
                    <th>价钱</th>
                </tr>
                </thead>
                <tbody>
                {% for foo in page_obj %}
                    <tr>
                        <td>{{ foo.id }}</td>
                        <td>{{ foo.name }}</td>
                        <td>{{ foo.price }}</td>
                    </tr>
                {% endfor %}
    
                </tbody>
            </table>
        
            {# 下面就是前端页面中显示页数,点击可以跳转,有上一页,下一页   #}
            <nav aria-label="Page navigation">
                <ul class="pagination">
                {#这里是设置点击上一页时,先判断该对象是否有上一页,再进行上一页的跳转,如果当前页为最开始一页,则不能点击上一页按钮#}
                    {% if page_obj.has_previous %}
                        <li>
                            <a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                                <span aria-hidden="true">上一页</span>
                            </a>
                        </li>
                    {% else %}
                        <li class="disabled">
                            <a href="" aria-label="Previous">
                                <span aria-hidden="true">上一页</span>
                            </a>
                        </li>
                    {% endif %}
                
                    {% for foo in PageRange %}
                        {% if foo == page_obj.number %}
                            <li class="active"><a href="?page={{ foo }}">{{ foo }}</a></li>
                        {% else %}
                            <li><a href="?page={{ foo }}">{{ foo }}</a></li>
                        {% endif %}
                    {% endfor %}
                
                {#这里是设置点击下一页时,先判断该对象是否有下一页,再进行下一页的跳转,如果当前页为最后一页,则不能点击下一页按钮#}
                    {% if page_obj.has_next %}
                        <li>
                            <a href="?page={{ page_obj.next_page_number }}" aria-label="Next">
                                <span aria-hidden="true">下一页</span>
                            </a>
                        </li>
                    {% else %}
                        <li class="disabled">
                            <a href="" aria-label="Next">
                                <span aria-hidden="true">下一页</span>
                            </a>
                        </li>
                    {% endif %}
    
                </ul>
            </nav>
        </div>
        <div class="col-md-2"></div>
    </div>
    </body>
    </html>
    
    额额,可能代码很多,就这样吧,详情可参考其他博客
  • 相关阅读:
    python3+Appium自动化12-H5元素定位环境搭建
    夜神模拟器连不上adb的解决办法
    性能测试工具LoadRunner04-LR之浏览器打不开
    性能测试工具LoadRunner03-LR之Virtual User Generator 脚本创建以及回放设置
    性能测试工具LoadRunner02-LR简介
    JavaScript Math 对象
    【ES6】模拟字符串拼接
    【ES6】var / let / const
    媒体查询,响应式布局
    数组操作
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/9991084.html
Copyright © 2011-2022 走看看