django中的数据分页
数据分页
Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中
属性
-
-
num_pages:页面总数
-
方法
-
page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常
异常exception
-
InvalidPage:当向page()传入一个无效的页码时抛出
-
PageNotAnInteger:当向page()传入一个不是整数的值时抛出
- EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
Page对象
创建对象
-
Paginator对象的page()方法返回Page对象,不需要手动构造
属性
-
object_list:当前页上所有对象的列表
-
number:当前页的序号,从1开始
-
paginator:当前page对象相关的Paginator对象
方法
-
has_next():如果有下一页返回True
-
has_previous():如果有上一页返回True
-
has_other_pages():如果有上一页或下一页返回True
-
next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
-
previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
-
len():返回当前页面对象的个数
-
迭代页面对象:访问当前页面中的每个对象
分页的视图:
from .models import Student from django.core.paginator import Paginator from django.shortcuts import render class StudentListView(View): def get(self,request,page=1): # 当前地址页码 try: current_page = int(page) except: current_page = 1 print(f"current_page={current_page}") student_list = Student.objects.all() # 分页器 paginator = Paginator(student_list, 5) # 当前分页对象 page = paginator.page(current_page) print(page) print(page.object_list) # 当前页要展示的数据 # django3.2以后提供了一个页码生成器 page_range = paginator.get_elided_page_range(current_page,on_each_side=3,on_ends=3) print(page_range) return render(request,"list.html",locals())
分页路由的视图:
from django.urls import path,re_path from . import views urlpatterns = [ re_path("student/(?P<page>\d*)", views.StudentListView.as_view()), ]
模板代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1" width="800"> <tr> <th>ID</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>班级</th> <th width="200">个性签名</th> </tr> {% for student in page.object_list %} <tr> <td>{{ student.id }}</td> <td>{{ student.name }}</td> <td>{{ student.sex }}</td> <td>{{ student.age }}</td> <td>{{ student.classmate }}</td> <td>{{ student.description }}</td> </tr> {% endfor %} </table> <p> {% for item in page_range %} <a href="{{ item }}">{{ item }}</a> {% endfor %} </p> <p> {% if page.has_previous %} <a href="1">首页</a> <a href="{{ page.previous_page_number }}">上一页</a> <a href="{{ page.previous_page_number }}">{{ page.previous_page_number }}</a> {% endif %} <a>{{ page.number }}</a> {% if page.has_next %} <a href="{{ page.next_page_number }}">{{ page.next_page_number }}</a> <a href="{{ page.next_page_number }}">下一页</a> <a href="{{ page.paginator.num_pages }}">尾页</a> {% endif %} </p> </body> </html>
ListView分页
ListView分页实现分页的视图:
class StudentListView(ListView): http_method_names = ['get'] # 限制当前视图类中提供哪些http请求视图方法 model = Student # 当前视图类中要操作的数据模型 context_object_name = 'students' # 模板变量 template_name = "students.html" # 模板路径 paginate_by = 5 # 每一页数据量[ListView内置视图类默认提供了分页器,分页对象在模板中通过page_obj来操作]
ListView分页实现分页的html模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <p>students</p> <table border="1" width="800"> <tr> <th>ID</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>班级</th> <th width="200">个性签名</th> </tr> {% for student in students %} <tr> <td>{{ student.id }}</td> <td>{{ student.name }}</td> <td>{{ student.sex }}</td> <td>{{ student.age }}</td> <td>{{ student.classmate }}</td> <td>{{ student.description }}</td> </tr> {% endfor %} </table> <p> {% if page_obj.has_previous %} <a href="?page=1">首页</a> <a href="?page={{ page_obj.previous_page_number }}">上一页</a> <a href="?page={{ page_obj.previous_page_number }}">{{ page_obj.previous_page_number }}</a> {% endif %} <a>{{ page_obj.number }}</a> {% if page_obj.has_next %} <a href="?page={{ page_obj.next_page_number }}">{{ page_obj.next_page_number }}</a> <a href="?page={{ page_obj.next_page_number }}">下一页</a> <a href="?page={{ page_obj.paginator.num_pages }}">尾页</a> {% endif %} </p> </body> </html>