简单讲解Django分页Paginator和Page的用法

在 Django 中实现分页功能非常简单。因为 Django 已经内置了两个处理分类的类。分别 是 Paginator 和 Page 。 Paginator 用来管理整个分类的一些属性, Page 用来管理当前这个分 页的一些属性。通过这两个类,就可以轻松的实现分页效果。以下对这两个类进行讲解。

Paginator 类

Paginator 是用来控制整个分页的逻辑的。比如总共有多少页,页码区间等.

创建Paginator对象:

class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True) ,其中的参 数解释如下:

  1. object_list (必选):列表,元组, QuerySet 或者是任何可以做切片操作的对象。会将这个里面的对象进行分页。 QuerySet带有count() or __len__()方法的列表,元组或其他可分片对象。为了保持一致的分页,QuerySet应该对s进行排序,例如在模型中使用order_by() 子句或缺省值ordering。

  2. per_page (必选):分页中,一页展示多少条数据,包含在页面上的最大项目数 ,不包括 orphans。

  3. orphans (可选):用来控制最后一页元素的个人如果少于 orphans 指定的个数的时候,就会将多余 的添加到上一页中。

  4. allow_empty_first_page(可选) :如果 object_list 没有任何数据,并且这个参数设置为 True , 那么就会抛出 EmptyPage 异常。

常用属性和方法:

  1. Paginator.page(number) :获取 number 这页的 Page 对象。

  2. count :传进来的 object_list 总共的数量。

  3. num_pages :总共的页数。

  4. page_range :页码的列表。比如 [1,2,3,4]


 Page 类:

得到Page对象:Paginator.page()
使用Page类构造对象生成Page对象

class Page(object_list, number, paginator)

常用属性和方法:

  1. has_next() :是否还有下一页。

  2. has_previous() :是否还有上一页。

  3. next_page_number() :下一页的页码。

  4. previous_page_number() :上一页的页码。

  5. object_list :在当前这页上的对象列表。

  6. number :当前的页码。

  7. paginator :获取 Paginator 对象。


例一:

#views.py
from django.shortcuts import render_to_response
from django.core.paginator import Paginator

def classify(request):
    """
    注意:objects可以为:列表/元组,Django QuerySet或任何其他对象
    """
    
    # 获取所有的对象的列表
    objects = goods.objects.all() # objects = ['john', 'paul', 'george', 'ringo']
    
    # 把对象分成 2 个一页
    paginator = Paginator(objects, 2)
    
    # 获取分页器里面的Page总数
    paginator.count     # -> 4
    
    # 获取Page的数量
    paginator.num_pages  # -> 2
    
    # 获取Page数目的范围(返回一个range_iterator对象)
    paginator.page_range  # -> range(1, 3)
    
    # 获得第一/二页的Page对象
      # <Page 1 of 2> 
      # 返回Page具有给定从1开始的索引的对象。InvalidPage如果给定页码不存在则引发 。
    page1 = paginator.page(1)
      # <Page 1 of 2>django2以上新增功能:返回Page具有给定的基于1的索引的对象
      #同时处理超出范围和无效页码(超出范围不会报错,默认返回最后一个Page对象)
    page2 = paginator.get_page(2)  
    
    # 获得第一个Page对象中的所有内容
    page1.object_list  # -> ['john', 'paul']
    
    # 判断下一个Page对象是否存在
    page2.has_next()  # -> False
    # 判断上一个Page对象是否存在 
    page1.has_previous()  #-> False
    
    # 判断是否还有其他Page对象
    page2.has_other_pages()   # True
    
    # 返回下一个Page对象的索引。如果没有,则触发EmptyPage
    page2.next_page_number()  # 报错
    # 返回上一个Page对象的索引。如果没有,则触发EmptyPage
    page2.previous_page_number()  # 1
    
    # 返回第一个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1)
    page1.start_index()  # 1
    # 返回第二个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1)
    page2.start_index()  # 3
    # 返回第二个Page对象里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1)
    page1.end_index()  # 2
    # 返回第二个分页器里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1)
    page2.end_index()  # 4
    # 获取当前页码
    current_page_num = page1.number    
    return render_to_response('index.html')

例二:

要求不复杂的话,直接使用以下的的设置即可,如有其它需求,可根据需求自定义。

使用方法:

1、导入分页所需的类

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

2、对需要的数据进行处理

def index(request):

    news = Article.objects.all().order_by('-id')#把需要分页的数据实例化

    page = request.GET.get('page')# 获取分页数
    paginator = Paginator(news, 10)#设置一页显示多少条数据(news为要分页的数据)
    try:
        news = paginator.page(page)  # 获取当前页码的记录
    except PageNotAnInteger:
        news = paginator.page(1)  # 如果用户输入的页码不是整数时,显示第1页的内容
    except EmptyPage:
        news = paginator.page(paginator.num_pages)  # 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容
    return render(request, 'index.html', locals())

3、前端分页效果:

<div class="pages">
    <ul>
        {# 首页按钮,固定page=1 #}
        <li><a href='?page=1'>首页</a></li>
        {# 如果上一页还有数据,那么让其可继续点击进入上一页 #}
        {% if news.has_previous %}
            <li><a href="?page={{ news.previous_page_number }}" data-ey_fc35fdc="html" data-tmp="1">上一页</a>
            </li>
            {# 如果上一页没有数据了,那么不让做任何操作 #}
        {% else %}
        {% endif %}

        {# 由后端经逻辑判断后的page_range页数列表进行迭代 #}
        {% for num in news.paginator.page_range %}
            {# 如果循环的页码与当前查看的页码相等,那么就让其高亮显示 #}
            {% if num == news.number %}
                <li class="thisclass"><a>{{ num }}</a></li>
            {% else %}
                <li><a href="?page={{ num }}" data-ey_fc35fdc="html" data-tmp="1">{{ num }}</a></li>
            {% endif %}
        {% endfor %}

        {# 如果当前页还有下一页,那么让其可以点击进入下一页 #}
        {% if news.has_next %}
            <li><a href="?page={{ news.next_page_number }}" data-ey_fc35fdc="html" data-tmp="1">下一页</a></li>
        {% endif %}

        {# 跳转到尾页,让page参数直接等于总页数 #}
        <li><a href='?page={{ paginator.num_pages }}'>尾页</a></li>
    </ul>
</div>

效果如图:

20220204133514.png


更多资料,可以查看官方文档。

https://docs.djangoproject.com/zh-hans/4.0/ref/paginator/#django.core.paginator.Paginator


文章评论 0