Django目录:https://blog.csdn.net/qq_41106844/article/details/105554082
为什么会有分页器
假如我们有一个图书管理系统,数据库里面存放了十万本书,如果没有分页器,书本信息会展示在一页上面,这显然不合理。
我们新建一个项目,然后配置如下:
fyq.fyq.urls.py
---------------
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/',views.index)
]
fyq.app01.views.py
------------------
from django.shortcuts import render
from app01.models import Book
def index(request):
#向数据库内添加100条数据
book_list=[]
for i in range(100):
book=Book(title="book_%s"%i,price=i*i)
book_list.append(book)
Book.objects.bulk_create(book_list)
return render(request,'index.html')
fyg.templates.index.html
------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>ok</p>
</body>
</html>
数据库截图
然后我们修改一下视图函数和页面,将数据展示出来:
fyq.app01.views.py
------------------
from django.shortcuts import render
from app01.models import Book
def index(request):
#查询出来所有的数据,然后传到页面上面。
book_list = Book.objects.all()
return render(request,'index.html',{"book_list":book_list})
fyg.templates.index.html
------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#把传上来的数据遍历输出#}
<ul>
{% for book in book_list %}
<li>{{ book.title }}----------{{ book.price }}</li>
{% endfor %}
</ul>
</body>
</html>
页面截图
显然我们把100本书全放到页面上了,现在我们对他进行分页,让他8本书一页。
fyq.app01.views.py
------------------
from django.shortcuts import render
from app01.models import Book
from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all()
#我们使用Django自带的分页器,把我们查询出来的数据分成每8个一份
paginator = Paginator(book_list,8)
#接受页面传来的get请求,如果没有接受到,默认为1(第一页)。
current_page_num = request.GET.get("page",1)
#通过页数获取相应的数据
current_page=paginator.page(current_page_num)
#传输
return render(request,'index.html',{"current_page":current_page})
fyg.templates.index.html
------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#同理#}
<ul>
{% for book in book_list %}
<li>{{ book.title }}----------{{ book.price }}</li>
{% endfor %}
</ul>
</body>
</html>
这样,我们访问url+?page=4,发起一次get请求。
页面截图
就访问到了第四页。
但是我么肯定不会这么写,因为没有网站会让用户通过url发起get请求来换页。
所以我们就要在修改一下:
fyq.app01.views.py
------------------
from django.shortcuts import render
from app01.models import Book
from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all()
paginator = Paginator(book_list,8)
current_page_num = request.GET.get("page",1)
#这里获取一下页数,用来切换上下页
currentPage = int(current_page_num)
current_page=paginator.page(current_page_num)
#传输的三个参数功能分别是:
#第一个参数是承载数据的可迭代对象
#第二个参数是承载总页数的对象
#第三个参数是承载当前页面的对象
return render(request,'index.html',{"current_page":current_page,"paginator":paginator ,"currentPage":currentPage})
fyg.templates.index.html
------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# bootcss的一个页码栏css#}
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h4>分页器</h4>
<ul>
{% for book in current_page %}
<li>{{ book.title }}----------{{ book.price }}</li>
{% endfor %}
</ul>
<ul class="pagination" id="pager">
{#首先判断我们当前的页码是否有上一页。#}
{#如果有上一页的话,用户点击上一页,跳转到上一页。#}
{#如果没有的话,禁止用户点击上一页。#}
{% if current_page.has_previous %}
<li class="previous"><a href="/index/?page={{ current_page.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}
{#通过page_range获取页码的列表,并将他遍历输出。#}
{#如果页面是当前页面的话,让他的class属性为 "item active"。#}
{#如果不是当前页面的话,就用 "item" 样式。#}
{#同时每一个页码都可以进行点击跳转。#}
{% for num in paginator.page_range %}
{% if num == currentPage %}
<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{#首先判断我们当前的页码是否有下一页。#}
{#如果有下一页的话,用户点击下一页,跳转到下一页。#}
{#如果没有的话,禁止用户点击下一页。#}
{% if current_page.has_next %}
<li class="next"><a href="/index/?page={{current_page.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %}
</ul>
</div>
</body>
</html>
页面截图
这样效果就出来了。
但是这样有一个毛病,他会显示我们所有的页码,这是一个bug,我们要改正他。
毛病1
fyq.app01.views.py
------------------
from django.shortcuts import render
from app01.models import Book
from django.core.paginator import Paginator
def index(request):
book_list = Book.objects.all()
paginator = Paginator(book_list,8)
current_page_num = request.GET.get("page",1)
currentPage = int(current_page_num)
current_page=paginator.page(current_page_num)
if paginator.num_pages > 11:
if currentPage - 5 < 1:
pageRange = range(1, 11)
elif currentPage + 5 > paginator.num_pages:
pageRange = range(currentPage - 5, paginator.num_pages + 1)
else:
pageRange = range(currentPage - 5, currentPage + 5)
else:
pageRange = paginator.page_range
return render(request,'index.html',{"current_page":current_page,"paginator":pageRange,"currentPage":currentPage})
fyg.templates.index.html
------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# bootcss的一个页码栏css#}
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h4>分页器</h4>
<ul>
{% for book in current_page %}
<li>{{ book.title }}----------{{ book.price }}</li>
{% endfor %}
</ul>
<ul class="pagination" id="pager">
{% if current_page.has_previous %}
<li class="previous"><a href="/index/?page={{ current_page.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}
{% for num in paginator %}
{% if num == currentPage %}
<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li class="next"><a href="/index/?page={{current_page.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %}
</ul>
</div>
</body>
</html>
修改截图
他就会变成只显示我们当前页面前后各五个页码。
注:分页器自带的方法和属性
book_list = Book.objects.all()
paginator = Paginator(book_list,8)
print("count:", paginator.count) # 数据总数
#count: 100
print("num_pages", paginator.num_pages) # 总页数
#num_pages 13
print("page_range", paginator.page_range) # 页码的列表
# page_range range(1, 14)
page1 = paginator.page(1) # 第1页的page对象
for i in page1: # 遍历第1页的所有数据对象
print(i)
#Book object (201)
#Book object (202)
#Book object (203)
#Book object (204)
#Book object (205)
#Book object (206)
#Book object (207)
#Book object (208)
print(page1.object_list) # 第1页的所有数据
#[<Book: Book object (201)>, <Book: Book object (202)>, <Book: Book object (203)>, <Book: Book object (204)>, <Book: Book object (205)>, <Book: Book object (206)>, <Book: Book object (207)>, <Book: Book object (208)>]
#让我们具体的获得一个页数对象
page2 = paginator.page(2)
print(page2.has_next()) # 是否有下一页
# True
print(page2.next_page_number()) # 下一页的页码
# 3
print(page2.has_previous()) # 是否有上一页
# True
print(page2.previous_page_number()) # 上一页的页码
# 3