Paginator实现分页

分页介绍:

from django.core.paginator import Paginator
#这里的p是Paginator对象
p=paginator(XX,1)
#所有属性:
p.count#对象总数
p.num_pages#页面总数
p.page_range#基于1的页数范围迭代器。比如:[1, 2, 3, 4]  这个属性可以更简单的解决模板中不支持直接range()的问题

#这里的page是Page对象
page=p.page(1)
page=p.get_page(1)
#属性
Page.object_list:当前页上所有对象的列表。
Page.number:当前页的序号,从1开始计数。
Page.paginator:当前Page对象所属的Paginator对象
#方法
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。

举例说明:

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)  # 对objects进行分页,虽然objects只是个字符串列表,但没关系,一样用。每页显示2条。

>>> p.count   # 对象个数
4
>>> p.num_pages  # 总共几页
2
>>> type(p.page_range)  # `<type 'rangeiterator'>` in Python 2.
<class 'range_iterator'>
>>> p.page_range  # 分页范围
range(1, 3)

>>> page1 = p.page(1) # 获取第一页
>>> page1
<Page 1 of 2>
>>> page1.object_list # 获取第一页的对象
['john', 'paul']

>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next()  # 判断是否有下一页
False
>>> page2.has_previous()# 判断是否有上一页
True
>>> page2.has_other_pages() # 判断是否有其它页
True
>>> page2.next_page_number() # 获取下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number() # 获取上一页的页码
1
>>> page2.start_index() # 从1开始计数的当前页的第一个对象
3
>>> page2.end_index() # 从1开始计数的当前页最后1个对象
4

>>> p.page(0)  # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page contains no results

要求:

  • 对查询出来的数据进行分页处理
  • 如果所有页码小于等于8,则展示所有页码
  • 点击所有页码数字,跳转到对应页

方法1:自定义过滤器解决模板不支持range问题,完成对页码的迭代

修改views的内容


from django.core.paginator import Paginator
def article_list(request):
      qry = ArticlePost.objects.all() #获取所有文章
      #进行分页操作,每页2条数据
      p = Paginator(qry,2)
      ##获取url中的页码,比如第一页,我们需要在url末尾中添加 ?page=1
      page = request.GET.get('page')
      ##获取相应的页码的数据,比如page=1,第一页,这里获取得到第一页的数据内容
      articles = p.get_page(page)
      ##获取一共分出来了多少页,前端展示所有页码数的时候需要用到该数
      page_nums = p.num_pages
      context={'articles':articles,'page_nums':page_nums}
      return render(request,'article/list.html',context)

修改模板内容

<!--前面的文章的展示部分忽略,主要展示分页部分如何编写-->
<!--如果不是第一页,则展示'上一页'这个按钮-->
<!--如果该页有上一页 has_previous判断django.core.paginator.Page对象是否有上一页-->
{% if articles.has_previous %}
      <!--Page对象.previous_page_number表示该页的上一页-->
      <a href="?page={{articles.previous_page_number}}"> 上一页</a>
{% endif %}

<!--展示所有页码-->

<!--这里的demo设置为 如果页码小于8就全部展示,否则就只展示1-5...然后n-1,n 比如一共有100页,页码展示为 1 2 3 4 5 ... 99 100 -->
{% if page_nums <= 8 %}
    <!--使用自定义过滤器,解决模板语言中不支持range()的问题 如何使用自定义模板参见:[https://www.cnblogs.com/alantammm/p/14303983.html]-->
    {% for i in page_nums|get_range %}
        {% if i == articles.number %}
            <!--这里是高亮展示当前页,这里用了bootstrip,需要引入,这里先不用关注这点-->
            <span class="current btn btn-danger btn-lg">
                {{ articles.number }}
            </span>
        {% else %}
            <!--其他页签就不用高亮展示了,但是点击其他页签的数据,会调到那一页去-->
            <a href="?page={{ i }}">{{ i }}</a>
        {% endif %}
    {% endfor %}
{% else %}
    <!--如果页数超过了8,就展示12345...n-1 n 页,中间用...展示-->
    {% for i in 5|get_range %}
        <!--高亮展示当前页 -->
        {% if i == articles.number %}
            <span class="current btn btn-danger btn-lg">
                {{ articles.number }}
            </span>
        {% else %}
            <!--其他页签就不用高亮展示了,但是点击其他页签的数据,会调到那一页去-->
            <a href="?page={{ i }}">{{ i }}</a>
        {% endif %}
    {% endfor %}
    <!--展示中间的...-->
    ...
    <!--对最后的两个页码进行单独处理,处理逻辑同上-->
    {% if page_nums|add:-1 == articles.number %}
        <span class="current btn btn-danger btn-lg">
                {{ articles.number }}
            </span>
    {% else %}
        <a href="?page={{ page_nums|add:-1 }}">{{ page_nums|add:-1 }}</a>
    {% endif %}

    {% if page_nums == articles.number %}
        <span class="current btn btn-danger btn-lg">
                {{ articles.number }}
            </span>
    {% else %}
        <a href="?page={{ page_nums }}">{{ page_nums }}</a>
    {% endif %}
{% endif %}

<!--如果不是最后一页,则展示'下一页'这个按钮 has_next判断django.core.paginator.Page对象是否有下一页-->
{% if articles.has_next %}
      <!--Page对象.next_page_number表示该页的上一页-->
      <a href="?page={{articles.next_page_number}}"> 下一页</a>
{% endif %}

方法2:运用page_range返回基于1的页数范围迭代器的属性,来实现页码的迭代

所得到的效果如下:

原文地址:https://www.cnblogs.com/alantammm/p/14304309.html