当前位置: 首页 > 工具软件 > Paginator > 使用案例 >

django paginator 学习笔记

周泰
2023-12-01

paginator简单介绍

paginator是django自带的分页工具

官网例子

from django.core.paginator import Paginator.
objects = ['john', 'paul', 'george', 'ringo']
p = Paginator(objects, 2)   #定义Paginator对象

>>> p.count       #2  =>因为每页2个数据
>>> p.num_pages   #2  =>每页2个,所以页数为2
>>> p.page_range  #range(1,3)  =>页数范围
>>> page1 = p.page(1) #<Page 1 of 2>
>>> page1.paginator.page_range   #range(1, 3) =>获取具体页数的对象后,从当前对象获取总页数范围的方法
>>> page1.number      #显示当前页数
>>> page1.object_list #['john','paul'] =>不知道为什么实际使用的时候并不需要这个(.object_list)直接用page1 就可以
>>> page1.has_next()  #True  =>因为有两页,有下一页
>>> page1.has_previous()         #False =>没有第0页
>>> page1.has_other_pages()      #判断是否只有一页
>>> page2.next_page_number()     #EmptyPage: That page contains no results  =>返回下一页,没有就报上面提示语
>>> page2.previous_page_number() #1 =>返回上一页
>>> page2.start_index()      #3 =>返回数据在list中的实际编号
>>> page2.end_index()        #4 =>最后一个数据的编号
>>> p.page(0)                #EmptyPage: That page number is less than 1
>>> p.page(3)                #EmptyPage: That page contains no results

使用

  1. views.py 导入库
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger
  1. 从前端页面获取页码

前端传参: ?sno=xx&?page=xx

<li>
	<a href="?sno={{ subject.no }}&page={{page_num}}">{{page_num}}<span class="sr-only">(current)</span>
	</a>
</li>
  1. 设置urls.py
urlpatterns = [
    path("teachers/",views.show_teachers),
]
  1. 后端views.py中获取传过来的参数
def show_teachers(request):
	#根据条件查询要展示的数据teachers 
	teachers = []
	if request.GET.get('sno'):
	    sno = int(request.GET.get('sno'))
	    subject = Subject.objects.only('name').get(no=sno)
	    teachers = Teacher.objects.filter(subject=subject)
	else:
	    subject = []
	    teachers = Teacher.objects.all()
	teachers_list = []							#这个是最后返回的值,上面官网例子中的 page1 = p.page(x) 对象
	limit = 8  									#每页显示的记录数
	paginator = Paginator(teachers,limit)		#Paginator定义
	page = request.GET.get('page',1)			#获取页数,默认第1页
	if page:
	   	try:
	    	teachers_list = paginator.get_page(page)   #获取某页对应的记录
	   	except PageNotAnInteger:
	      	teachers_list = paginator.page(1)      #第一页
	    except EmptyPage:
	        teachers_list = paginator.page(paginator.num_pages)  #最后一页
	return render(request,'polls/teachers.html',{
	            'subject':subject,
	            'teachers':teachers_list
	        })
  1. 再返回前端显示页数

这时就能看出 传递参数是 teachers_list = paginator.page(page) (注:官网例子中对应的 page1 = p.page(1))
因为这样才能使用 teachers_list.has_previous等 teachers_list.number 等方法

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="pull-right" style="margin-right: 100px;margin-top: 5px;">
    <!--分页功能-->
    <nav>
        <ul class="pagination">
            <!--分页功能previous方向箭头代码-->
            {% if teachers.has_previous %}
            <li class="enabled">
                <a href="?sno={{ subject.no }}&?page={{ teachers.previous_page_number }}" aria-label="Previous">
                    <span aria-hidden="true">&laquo</span>
                </a>
            </li>
            {% endif %}
            <!--分页功能显示页码的 中间部分 -->
            {% for page_num in teachers.paginator.page_range %}
                {% if page_num == teachers.number %}
                    <li class="active">
                        <a href="#">
                            {{page_num}}<span class="sr-only">(current)</span>
                        </a>
                    </li>
                {% else %}
                    <li>
                        <a href="?sno={{ subject.no }}&page={{page_num}}">
                            {{page_num}}<span class="sr-only">(current)</span>
                        </a>
                    </li>
                {% endif %}
            {% endfor %}
            <!--分页功能,下一页功能-->
            {% if teachers.has_next %}
                <li class="enabled">
                    <a href="?sno={{ subject.no }}&?page={{ teachers.next_page_number }}" aria-label="last">
                        <span aria-hidden="true" >&raquo;</span>
                    </a>
                </li>
            {% endif %}
        </ul>
    </nav>
</div>

问题

  1. 确实是对视觉体验有提升,但为什么Paginator 能减少数据库读取数据压力呢?
    后端查询明明每次都是一样的量,每次都是查询完了再把结果赋给Paginator对象,那跟不分页一样吗…有什么读取数据压力上的优势
  2. object_list = paginator.get_page(page) 和 object_list = paginator.page(page) 这两种的都可以用…好像get_page是新的
  3. 前端页面中的(页数范围)teachers.paginator.page_range 不知道为什么 page_range 这个方法在html页面中需要加上 paginator 才行,
    答: 官方教程里面却是 p.page_range , 而没有特地写上 page1.paginator.page_range 搞得我混乱了
    这两是一样的结果: range(1,3)
  1. from django.shortcuts import render,redirect
    redirect 无法传递参数 ,那怎么用redirect传递参数呢?

感觉

前端知识缺乏,学习django需要有前端知识基础,特别是javascript 只能抄
的确用bootstrap,jquery的页面视觉效果很棒

其他

  • 前端传参时参数前面带问号: ?page=xx ,难道是指如果没有xx这个值就不会传page这个参数的意思吧?

  • span

<span> 标签提供了一种将文本的一部分或者文档的一部分独立出来的方式
<p>我的母亲有 <span style="color:blue;font-weight:bold">蓝色</span>
  • &laquo,&raquo转义字符
  <li><a href="#">&laquo;上一页</a></li>
  <li><a href="#">下一页&raquo;</a></li>

效果如下:

  • «上一页
  • 下一页»
    • href 标签中传递(多个参数) --------------- 用 & 符号隔开
    <a href="?sno={{ subject.no }}&page={{page_num}}">
      {{page_num}}<span class="sr-only">(current)</span>
    </a>
    
    • xlwt库保存 excel文件时文件后缀不能是(.xlsx),只能是(.xls)
      网上说openpyxl 可以保存成(.xlsx)

    参考

    django官方文档3.0,paginator部分

 类似资料: