美文网首页Python
Django自带分页模块详解

Django自带分页模块详解

作者: 摘花是个好习惯 | 来源:发表于2018-12-18 23:22 被阅读0次
    page = Paginator(obj_list, per_page)

    object_list : 一个列表,元祖或则Django 的Queryset 对象 或则其他对象带有 count() or len()的方法
    per_page :就是1页显示几条数据

    page对象的方法和属性
    • page .has_next() ----
      如果有下一页,则返回True。

    • page .has_previous() ----
      如果有上一页,返回 True。

    • page .has_other_pages()
      如果有上一页或下一页,返回True。

    • page .next_page_number()
      返回下一页的页码。如果下一页不存在,抛出InvalidPage异常。

    • page .previous_page_number()
      返回上一页的页码。如果上一页不存在,抛出InvalidPage异常。

    • page .start_index()
      返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3。

    • page .end_index()
      返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index() 会返回 4。

    • page.number
      当前页码

    • page.paginator
      相关的Paginator对象。
    page.paginator对象的属性
    • per_page: 每页显示条目数量
    • count: 数据总个数
    • num_pages:总页数
    • page_range:总页数的索引范围,页码的范围,从1开始,例如[1, 2, 3, 4]。
    后端代码
    # 得到表的对象的列表,因为 Paginator 第一个参数必须是可迭代的,第二个参数是每页展示的个数
    model_all = admin_class.model.objects.all()
    paginator = Paginator(model_all,1)
    current_page = request.GET.get('page')
    
    
    try:
        # paginator.page()得到的是一页的对象列表,所以前端不用再对
        # admin_class.model.objects.all()进行循环,而是循环posts
        posts = paginator.page(current_page)
     # 防止用户输入非法字符
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    
    前端代码
     <nav aria-label="">
         <ul class="pagination">
                            {# 判断posts是否有上一页#}
              {% if posts.has_previous %}
                  <li class=""><a href="?page=1">首页</a></li>
                  <li class=""><a href="?page={{ posts.previous_page_number }}">上一页</a></li>
              {% endif %}
    
                           {# 中间显示页码需要对所有的页码进行循环 #}
                           {# posts.paginator得到的又是一个paginator对象,只有paginator对象才有page_range方法 #}
              {% for loop_counter in posts.paginator.page_range %}
                   {# 简单标签 #}
                   {% loop_display_page loop_counter posts %}
              {% endfor %}
    
                            {# 判断posts是否有下一页#}
              {% if posts.has_next %}
                   <li class=""><a href="?page={{ posts.next_page_number }}">下一页</a></li>
                   <li><a href="?page={{ posts.paginator.num_pages }}">尾页</a></li>
              {% endif %}
          </ul>
     </nav>
    
    简单标签代码
    @register.simple_tag
    def loop_display_page(loop_counter, posts):
        cls =''
        # 需求为只显示当前页码加左右两边各两个页码
        if abs(posts.number-loop_counter)<=2:
            # 如果循环到的页码等于当前页码,给页码加上 active 样式
            if loop_counter == posts.number:
                cls = "active"
            return mark_safe('<li class="%s"><a href="?page=%s">%s</a></li>'%(cls,loop_counter,loop_counter))
        # 防止分页最末尾出现 None
        return ''
    

    分页改良版

    效果图:


    image.png

    代码如下:

    @register.simple_tag
    def loop_display_page(posts, filter_conditions):
        fil = ''
        ele = ''
        flag = False
        for k ,v in filter_conditions.items():
            fil += '&%s=%s'%(k,v)
    
        for page_num in posts.paginator.page_range:
            # 前两页,后两页,当前页的两边都显示,其余的··表示
            if page_num < 3 or page_num > posts.paginator.num_pages-2 or abs(posts.number - page_num) <=1:
                cls =''
                if page_num == posts.number:
                    flag = False
                    cls = 'active'
                ele += '<li class="%s"><a href="?page=%s%s">%s</a></li>'%(cls,page_num,fil,page_num)
    
            elif flag == False:
                ele += '<li><a>··</a></li>'
                flag = True
    
        return mark_safe(ele)
    

    !注意标志位的使用

    相关文章

      网友评论

        本文标题:Django自带分页模块详解

        本文链接:https://www.haomeiwen.com/subject/yhsrkqtx.html