Django - Paginator 分页优化

邬飞捷
2023-12-01

Paginator()

功能实现分页
object_list当前页的对象列表
has_next()有无下一页
has_ previous()有无上一页
has_other_pages()有无其他页
next_page_number()下一页页码
previous_page_number()上一页页码
start_index()返回当前页第一个对象的在所有对象中的索引,注意,从1开始
end_index()返回当前页最后一个对象在所有对象中的索引,注意,从1开始
paginator所关联的Paginator对象
>>> from django.core.paginator import Paginator#导入Paginator模块
>>> list1=[i for i in range(0,150)]#使用列表生成器生成一个包含150个数字的列表
>>> page1=Paginator(list1,10)#生成一个Paginator对象
>>> print(page1.count)#打印总的记录数,即列表list1的长度
150
>>> print(page1.num_pages)#打印总的页数,即总记录数除以每页显示的条目数
15
>>> print(page1.page_range)#页数的列表
range(1, 16)
>>> print(page1.page(1))#打印第一页的page对象
<Page 1 of 15>
>>> page1.page(1).object_list#打印第一页的所有记录
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> page1.page(2).object_list#打印第二页的所有记录
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> page1.page(2).next_page_number()#打印当前的页(第2页)的下一页的页码
3
>>> page1.page(2).has_next()#第2页是否有下一页
True
>>> page1.page(2).has_previous()#第2页是否有上一页
True
>>> page1.page(2).has_other_pages()#第2是否有其他页
True
>>> page1.page(2).start_index()#第2页第一条记录的序号
11
>>> page1.page(2).end_index()#第2页最后一条记录的序号
20
>>> page1.page(0)#第0页是否有记录,会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    ...
    raise EmptyPage(_('That page number is less than 1'))
django.core.paginator.EmptyPage: <exception str() failed>
>>> page1.page(15)#打印第15页的对象
<Page 15 of 15>
  1. 后台分页的数据,根据你查找的页数,将数据分割
pageIndex = request.GET.get('pageIndex')  // 拿到页码参数 
pageSize = request.GET.get('pageSize')  # 获取以每页 * 条 -每页的数量
pageInator = Paginator(all_page, pageSize)
contacts = pageInator.page(pageIndex)

例子:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.css' %}">
</head>
<body>
<div class="container">
    <h4>分页器</h4>
    <ul>
        #遍历boot_list中的所有元素
        {% for book in book_list %}
            #打印书籍的名称和价格
            <li>{{ book.title }} {{ book.price }}</li>
        {% endfor %}
    </ul>
    <ul class="pagination" id="pager">
        {#上一页按钮开始#}
        {# 如果当前页有上一页#}
        {% if book_list.has_previous %}
            {#  当前页的上一页按钮正常使用#}
            <li class="previous"><a href="/?page={{ book_list.previous_page_number }}">上一页</a></li>
        {% else %}
            {# 当前页的不存在上一页时,上一页的按钮不可用#}
            <li class="previous disabled"><a href="#">上一页</a></li>
        {% endif %}
        {#上一页按钮结束#}
        {# 页码开始#}
        {% for num in paginator.page_range %}
 
            {% if num == currentPage %}
                <li class="item active"><a href="/?page={{ num }}">{{ num }}</a></li>
            {% else %}
                <li class="item"><a href="/?page={{ num }}">{{ num }}</a></li>
 
            {% endif %}
        {% endfor %}
        {#页码结束#}
        {# 下一页按钮开始#}
        {% if book_list.has_next %}
            <li class="next"><a href="/?page={{ book_list.next_page_number }}">下一页</a></li>
        {% else %}
            <li class="next disabled"><a href="#">下一页</a></li>
        {% endif %}
        {# 下一页按钮结束#}
    </ul>
</div>
</body>
</html>

VIews 视图:

#导入render和HttpResponse模块
from django.shortcuts import render,HttpResponse
 
#导入Paginator,EmptyPage和PageNotAnInteger模块
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
 
#从Django项目的应用中导入模块
from app01.models import *
 
def index(request):
 
    #获取Book数据表中的所有记录
    book_list=Book.objects.all()
 
    #生成paginator对象,定义每页显示10条记录
    paginator = Paginator(book_list, 10)
 
    #从前端获取当前的页码数,默认为1
    page = request.GET.get('page',1)
    
    #把当前的页码数转换成整数类型
    currentPage=int(page)
 
    try:
        print(page)
        book_list = paginator.page(page)#获取当前页码的记录
    except PageNotAnInteger:
        book_list = paginator.page(1)#如果用户输入的页码不是整数时,显示第1页的内容
    except EmptyPage:
        book_list = paginator.page(paginator.num_pages)#如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容
 
    return render(request,"index.html",locals())

分页改进

避免数据量过于大,需要将数据全部导出在分页,造成查询时间过于长,改善方法:

 '''显示 分页'''
        # 获取当前页数
        pageIndex = int(request.GET.get('pageIndex'))
        # 获取每页的个数
        pageSize = int(request.GET.get('pageSize'))

        # total count
        totalSize = AccessDetails.objects.count()
        # 计算起始数
        start = (pageIndex - 1) * pageSize
        # 计算结束数
        end = start + pageSize

        data = serializers.serialize("json",
                AccessDetails.objects.all().order_by('-date_in', 'id')[start:end])
        data = json.loads(data)
        all_page = []
        for record in data:
            record['fields']['pk'] = record['pk']
            fields = record['fields']
            all_page.append(fields)
        res['count'] = totalSize
        res['data'] = all_page
        res['msg'] = True
 类似资料: