1.使用分页器前需要准备好数据:
准备工作:创建项目和应用。在setting中设置该有的配置以及路由。
在创建的app中的models.py文件中创建该数据库模型:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=1)
class Meta:
db_table = 'Book'
生成该模型:
python manage.py makemigrations
python manage.py migrate
绑定路由:
from django.contrib import admin
from django.urls import path
from app1 import views
urlpatterns = [
path("admin/", admin.site.urls),
path("create/", views.create),
path("books/", views.index),
]
在views.py文件中插入数据:
from django.shortcuts import render,HttpResponse
from .models import Book
def create(request):
Booklist=[]
for i in range(101):
Booklist.append(Book(title="book"+str(i),price=i*2))
Book.objects.bulk_create(Booklist)
return HttpResponse("插入成功")

2.分页器Paginator的基础语法
views.py:
from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all() #总数据
#(1)分页对象
paginator = Paginator(book_list,5) #每页5条数据
#分页信息
print(paginator.count) #总数据的数量 1000
print(paginator.num_pages) #分页的数量 1000/5=200页
print(paginator.page_range) #分页列表range(1,201)
#(2)获取某页对象
visit_page_num = request.GET.get('page',1)#没有在导航栏输入page的话默认为1
page = paginator.page(visit_page_num) #paginator.page(哪一页的数据)
#获取该页的所有数据
# 方式一:
print(page.object_list)
# #方式二:
for book in page:
print(book)
#某页对象其他属性
print(page.next_page_number()) #下一页
print(page.previous_page_number()) #上一页
print(page.has_next()) #是否有下一页 True
print(page.has_previous()) #是否有上一页 True
# page_book_list = page.object_list
return render(request,'index.html',{"page":page})
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{% for book in page %}
<li>{{ book.title }}:{{ book.price }}</li>
{% endfor %}
</ul>
</body>
</html>

3.分页器Paginator的调整
问题一:
page页数超过或低于该模型的最大页数时:

from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all() #总数据
#(1)分页对象
paginator = Paginator(book_list,5) #每页5条数据
#分页信息
print(paginator.count) #总数据的数量 1000
print(paginator.num_pages) #分页的数量 1000/5=200页
print(paginator.page_range) #分页列表range(1,201)
try: #使用try的作用,把低于或者超过该页数的重定向成第一页数
#(2)获取某页对象
visit_page_num = request.GET.get('page',1)#没有在导航栏输入page的话默认为1
page = paginator.page(visit_page_num) #paginator.page(哪一页的数据)
#获取该页的所有数据
# 方式一:
print(page.object_list)
# #方式二:
for book in page:
print(book)
#某页对象其他属性
print(page.next_page_number()) #下一页
print(page.previous_page_number()) #上一页
print(page.has_next()) #是否有下一页 True
print(page.has_previous()) #是否有上一页 True
# page_book_list = page.object_list
except Exception as e:
page = paginator.page(1) #使用try的作用,把低于或者超过该页数的重定向成第一页数
return render(request,'index.html',{"page":page})

问题二:
在这里只是前端的页面,怎么点击按钮都没用,该怎么办?
在前端和后端中添加页数的按钮,不可能让用户在导航栏输入page吧?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
<ul>
{% for book in page %}
<li>{{ book.title }}:{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</body>
</html>

在后端中我们可以使用哪个法子可以把所有的页数展示出来?
那么就是上面提及到的
print(paginator.page_range) #分页列表range(1,14)
顾名思义,page_range就是一个列表,我们可以for循环它,来展示我们的页数。
所有我们要在前端(更改成for循环)和后端(导入前端模板paginator参数)代码中更改:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
<ul>
{% for book in page %}
<li>{{ book.title }}:{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
{% for i in paginator.page_range %}
<li><a href="">{{ i }}</a></li>
{% endfor %}
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</body>
</html>
from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all() #总数据
#(1)分页对象
paginator = Paginator(book_list,5) #每页5条数据
#分页信息
print(paginator.count) #总数据的数量 1000
print(paginator.num_pages) #分页的数量 1000/5=200页
print(paginator.page_range) #分页列表range(1,201)
try: #使用try的作用,把低于或者超过该页数的重定向成第一页数
#(2)获取某页对象
visit_page_num = request.GET.get('page',1)#没有在导航栏输入page的话默认为1
page = paginator.page(visit_page_num) #paginator.page(哪一页的数据)
#获取该页的所有数据
# 方式一:
print(page.object_list)
# #方式二:
for book in page:
print(book)
#某页对象其他属性
print(page.next_page_number()) #下一页
print(page.previous_page_number()) #上一页
print(page.has_next()) #是否有下一页 True
print(page.has_previous()) #是否有上一页 True
# page_book_list = page.object_list
except Exception as e:
page = paginator.page(1) #使用try的作用,把低于或者超过该页数的重定向成第一页数
return render(request,'index.html',{"page": page,"paginator":paginator})
结果:

解决按钮不能点击问题:
{% for i in paginator.page_range %}
<li><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% endfor %}
我在前端的a标签里面添加我们的路径,i变量为页数。

然后便可点击。
按钮的颜色:
意思点击某个按钮时,这个按钮会变成深色,让用户知道自己在哪一页。
原理:在导航栏的page的参数值中,前端的模板语法获取当前页数的page值,然后再前端模板语法中把page值加颜色深,之后就在前端中可以看到页数的值加深

前端判断:
里面的visit_page_num从后端获取
{% for i in paginator.page_range %}
{% if i == visit_page_num %}
<li class="active"><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
后端导入:vist_page_num
return render(request, 'index2.html', {"page": page, "paginator": paginator,"visit_page_num": visit_page_num})
结果:

问题三:
添加上一页和下一页的功能。
<ul class="pagination">
<li>
<a href="/books/?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
{% for i in paginator.page_range %}
{% if i == visit_page_num %}
<li class="active"><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<a href="/books/?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
</ul>
但是有存在的问题,就是到达第一页的时候,再点击上一页会报错,这是因为该方法有检查上一页是否有值,如果没有值那么就会报错。(下一页也是)。
所以我们要添加判断:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h4>分页器</h4>
<ul>
{% for book in page %}
<li>{{ book.title }} -----{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="/books?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="/books?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %}
{% for i in paginator.page_range %}
{% if i == visit_page_num %}
<li class="active"><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="/books/?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="/books?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="/books?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</body>
</html>
原理图:

1001

被折叠的 条评论
为什么被折叠?



