77.Django分页器

1. 概述

​ 分页,就是当我们在页面中显示一些信息列表,内容过多,一个页面显示不完,需要分成多个页面进行显示时,使用的技术就是分页技术。

​ 在django项目中,一般是使用3种分页的技术:

  1. 自定义分页功能,所有的分页功能都是自己实现
  2. django的插件 django-pagination 实现
  3. django自带的分页器 paginator
    这里将会讲解第三种

2. 分页器相关对象

​ 分页器的对象在 django/core/paginator.py 模块中,主要包括Paginator类和Page类:

2.1 Paginator类

  1. 初始化方法_init_(self, object_list, per_page, orphans=0,allow_empty_first_page=True):

    • object_list:可以是QuerySet、带有count()或_len_()方法的列表、元组或其它可切片的对象,如果是QuerySet,应该进行排序,使用order_by()子句或者有默认的ordering
    • per_page:每个页面上显示的项目数目,不包括orphans部分
    • orphans:默认为0,如果最后一页显示的数目小于等于该数值,那么则将最后一页的内容(假设数为N)添加到倒数第二页中去,这样的话倒数第二页就成了最后一页,显示的数目为:per_page+N
    • allow_empty_first_page:默认为True,允许第一页显示空白内容,如果设置为False,那么当object_list为空时,抛出EmptyPage错误
  2. 方法

    1. get_page(self, number)

      • numer:指定页码数,正确值应该是大于等于1的整数

      返回指定number的Page对象,同时还处理超出范围和无效页码,如果number不是数字,则返回第一页,如果number为负数或大于最大页数,则返回最后一页。

    2. page(self, number)

      • numer:指定页码数,正确值应该是大于等于1的整数

      返回指定number的Page对象,不处理异常,如果number无效,则抛出 InvalidPage 错误

  3. 属性

    1. count:项目总条数,调用该属性时,优先调用object_list的count()方法,没有count()方法才尝试len(object_list)方法
    2. num_pages:总页码数
    3. page_range:从1开始的页码迭代器,代码:range(1, self.num_pages + 1)

2.2 Page类

​ 一般情况下,不会手动实例化该类,而是通过Paginator的page或者get_page方法获取

  1. 初始化方法_init_(self, object_list, number, paginator):

    • object_list:当页显示的object_list对象,object_list可以是QuerySet、带有count()或_len_()方法的列表、元组或其它可切片的对象
    • number:页码数
    • paginator:Paginator类的实例
  2. 方法

    主要的方法都是用来做逻辑判断的,以此来决定页面中显示的诸如:上一页、下一页,首页,末页等

    1. has_next():如果有下一页则返回True

    2. has_previous():如果有上一页,则返回True

    3. has_other_pages():如果有上一页或者下一页,则返回True

    4. next_page_number():返回下一页编号,如果下一页不存在则引发 InvalidPage 错误

    5. previous_page_number():返回上一页编号,如果上一页不存在则引发 InvalidPage 错误

    6. start_index() :返回页面上第一个对象的从1开始的索引,相对于分页器列表中的所有对象。例如,当为每页包含2个对象的5个对象的列表进行分页时,第二个页面Page对象的start_index返回3

    7. end_index() :返回页面上最后一个对象的从1开始的索引,相对于分页器列表中的所有对象。例如,当为每页包含2个对象的5个对象的列表进行分页时,第二个页面Page对象的end_index返回4

  3. 属性

    其实就是初始化方法中的3个参数

    1. object_list:对应的object_list
    2. number:该对象的所处的页码数,从1开始
    3. paginator:关联的Paginator实例

3. 项目中应用

翻页显示数据实现
orphans参数的使用——让最后一页的少数据去到前一面

  1. 新建django项目:paginator_study,子应用:paginator_app
  2. 在mysql数据库新建 paginator_study 库
  3. settings中配置数据库:
   DATABASES = {
       'default': {
           'ENGINE': 'django.db.backends.mysql',
           'NAME': 'paginator_study',
           'USER': 'root',
           'PASSWORD': '123456',
           'HOST': '127.0.0.1',
           'PORT': '3306',
       }
   }
  1. 建立模型并随机生成数据方法:
from django.db import models
import random
import string
# Create your models here.
class Student(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    sex = models.IntegerField(choices=((1,'男'),(2,'女')),default=1)
    card_no = models.CharField(max_length=18)

    
    @classmethod
    def insert_student_data(cls,num):
        # 随机生成字符串
        def random_str(str,length):
            return ''.join(random.choices(str,k=length)) # 按照str内容,随机插入length个数据
        student_list = []
        for i in range(num):
            student_list.append(Student(
                name = random_str(string.ascii_lowercase, 10),# 从小写字母中,随机插入10位
                age = random.randint(18,30),
                sex = random.choice([1,2]),
                card_no = random_str(string.digits,18)
            ))
        Student.objects.bulk_create(student_list)
    


Django调用函数单独执行的方法
在这里插入图片描述

  1. 迁移数据库
   python manage.py makemigrations
   
   python manage.py migrate paginator_app
  1. 配置templates在settings
import os
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')],
  1. 配置分页在settings
# 配置分页页数
PAGE_SIZE = 10
# 配置最后一页最小数
ORPHANS = 5

url

from django.contrib import admin
from django.urls import path,include
from . import views
urlpatterns = [
    path('student_list/',views.student_list),
    path('student_page_list/',views.student_page_list)
]

templates

<!DOCTYPE html>
<html lang="en">
    {% load static %}
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="{% static 'paginator_app/css/page_style.css' %}">
</head>
<body>
    <div>
        <table>
            <tr>
                <th>序号</th>
                <th>学生姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>身份证号</th>
            </tr>
            {% for student in student_page.object_list %}
            <tr>
                <!-- <td>{{forloop.counter}}</td> -->
                <td>{{student_page.start_index|add:forloop.counter0}}</td>
                <td>{{student.name}}</td>
                <td>{{student.age}}</td>
                <td>{{student.sex}}</td>
                <td>{{student.card_no}}</td>
            </tr>
            {% endfor %}
        </table>
        <nav>
            <ul>
                <li><a href="?num=1"><span>首页</span></a></li>
                <li>
                    {%if student_page.has_previous %}
                    <a href="?num={{student_page.previous_page_number}}"><span>上一页</span></a>
                    {% else %}
                    <span>上一页</span>
                    {%endif%}
                </li>
                {% for i in page_range_list%}
                {% if student_page.number == i%}
                <li><a href="?num={{i}}"><span><strong>{{i}}</strong></span></a></li>
                {%else%}
                <li><a href="?num={{i}}"><span>{{i}}</span></a></li>
                {%endif%}
                {%endfor%}
                <li>
                    {% if student_page.has_next %}
                    <a href="?num={{student_page.next_page_number}}"><span>下一页</span></a>
                    {% else %}
                    <span>下一页</span>
                    {% endif %}
                </li>
                <li><a href="?num={{student_page.paginator.num_pages}}"><span>末页</span></a></li>
                总共是{{student_page.paginator.num_pages}}页
                当前是第{{student_page.number}}页
            </ul>
        </nav>
    </div>
</body>
</html>

views

from django.shortcuts import render
from .models import Student
from django.core.paginator import Paginator, Page
from django.conf import settings
# Create your views here.
def student_list(request):
    # 查询学生列表
    student_list = Student.objects.all()
    return render(request, 'paginator_app/student_list.html',{'student_list':student_list})

def get_range_list(num, total_page, size = 9):
    min = num-int(size/2)
    min = min if min>=1 else 1
    max = min + size -1
    max = max if max <= total_page else total_page
    return range(min,max+1)

def student_page_list(request):
    # 获取当前查询的是第几页
    num = request.GET.get('num')
    student_list = Student.objects.all()
    # 创建Paginator实例对象
    paginator = Paginator(student_list, settings.PAGE_SIZE, settings.ORPHANS)
    # paginator = Paginator(student_list,10)
    # 获取Page对象
    student_page = paginator.get_page(num)
    page_range_list = get_range_list(student_page.number,paginator.num_pages,settings.RANGE_LIST_SIZE)
    return render(request, 'paginator_app/student_page.html',{'student_page':student_page,'page_range_list':page_range_list})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成为数据分析师的开发工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值