Django的分页器

1 前期准备

创建一个数据库,用于存放数据

mysql> create database pager default charset=utf8;

mysql> use pager;

setting注册

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'pager',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '123456',
}
}

配置__init__

import  pymysql
pymysql.install_as_MySQLdb()

模型数据models.py

from django.db import models

# Create your models here.
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)

执行数据迁移操作

root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py makemigrations

root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py migrate

数据库

mysql> desc app01_book;

配置路由

from django.urls import  path,re_path
from app01 import views urlpatterns = [
path('login_fbv/',views.login),
path('login_cbv/', views.Login.as_view()),
path('book_list/',views.Booklist.as_view()),
]

views文件

#分页器
from app01.models import Book
#from app01 import models
import random
class Booklist(View):
def get(self,request):
for i in range(1,101):
Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
Book.objects.create
return render(request,"book_list.html")

book_list.html

#分页器
from app01.models import Book
#from app01 import models
import random
class Booklist(View):
def get(self,request):
for i in range(1,101):
Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
Book.objects.create
return render(request,"book_list.html")

访问http://127.0.0.1:8000/app01/book_list/

查看数据库

mysql> select * from app01_book;

这种方式比较慢

方法二:

mysql> delete from app01_book;

#分页器
from app01.models import Book
#from app01 import models
import random
class Booklist(View):
def get(self,request):
temp_list = []
for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
Book.objects.bulk_create(temp_list)
return render(request,"book_list.html")

访问http://127.0.0.1:8000/app01/book_list/

mysql> select * from app01_book;

+-----+----------+--------+
| id | title | price |
+-----+----------+--------+
| 101 | book_1 | 195.00 |
| 102 | book_2 | 95.00 |
| 103 | book_3 | 69.00 |
| 104 | book_4 | 118.00 |
| 105 | book_5 | 108.00 |
| 106 | book_6 | 165.00 |
....略...
| 199 | book_99 | 34.00 |
| 200 | book_100 | 99.00 |
+-----+----------+--------+

已经插入数据,速度比较快,同时及时注释掉创建数据的内容

显示书名和价格

#分页器
from app01.models import Book
#from app01 import models
import random
class Booklist(View):
def get(self,request):
#temp_list = []
#for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
# temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
#Book.objects.bulk_create(temp_list)
book_list = Book.objects.all()
#把book_list传到模板层
return render(request,"book_list.html",{
"book_list":book_list,
})

book_list.html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>图书列表</h3>
<ul>
{% for book in book_list %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
</body>
</html>

访问http://127.0.0.1:8000/app01/book_list/

已经显示到页面上,导入分页器

2 分页器语法

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
#temp_list = []
#for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
# temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
#Book.objects.bulk_create(temp_list)
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
print("count", paginator.count) # 数据的总数
print("num_pages", paginator.num_pages) # 分页的总页数
print("page_range", paginator.page_range) # 页数的范围列表 #把book_list传到模板层
return render(request,"book_list.html",{
"book_list":book_list,
})

访问http://127.0.0.1:8000/app01/book_list/,调试输出

count 100     #100条数据
num_pages 10 #10页
page_range range(1, 11) #1-11
[10/Apr/2020 14:36:42] "GET /app01/book_list/ HTTP/1.1" 200 4906

显示每一页数据

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
#temp_list = []
#for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
# temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
#Book.objects.bulk_create(temp_list)
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#print("count", paginator.count) # 数据的总数
#print("num_pages", paginator.num_pages) # 分页的总页数
#print("page_range", paginator.page_range) # 页数的范围列表
page1 = paginator.get_page(1)
for i in page1:
print(i)
#把book_list传到模板层
return render(request,"book_list.html",{
"book_list":book_list,
})

访问http://127.0.0.1:8000/app01/book_list/,调试输出

Book object (101)
Book object (102)
Book object (103)
Book object (104)
Book object (105)
Book object (106)
Book object (107)
Book object (108)
Book object (109)
Book object (110)

获取对象

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
#temp_list = []
#for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
# temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
#Book.objects.bulk_create(temp_list)
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#print("count", paginator.count) # 数据的总数
#print("num_pages", paginator.num_pages) # 分页的总页数
#print("page_range", paginator.page_range) # 页数的范围列表
page1 = paginator.get_page(1)
     page2 = paginator.get_page(2)
#for i in page1:
# print(i)
print(page1.object_list)
#把book_list传到模板层
return render(request,"book_list.html",{
"book_list":book_list,
})

访问http://127.0.0.1:8000/app01/book_list/,调试输出,是query_set对象

<QuerySet [<Book: Book object (101)>, <Book: Book object (102)>, <Book: Book object (103)>, <Book: Book object (104)>, <Book: Book object (105)>, <Book: Book object (106)>, <Book: Book object (107)>, <Book: Book object (108)>, <Book: Book object (109)>, <Book: Book object (110)>]>

查看是否有上一页或者下一页

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
#temp_list = []
#for i in range(1,101):
#Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
# temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
#Book.objects.bulk_create(temp_list)
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#print("count", paginator.count) # 数据的总数
#print("num_pages", paginator.num_pages) # 分页的总页数
#print("page_range", paginator.page_range) # 页数的范围列表
#page1 = paginator.get_page(1)
page2 = paginator.get_page(2)
#for i in page1:
# print(i)
#print(page1.object_list)
print(page2.has_next()) # 是否有下一页
print(page2.next_page_number()) # 下一页的页码
print(page2.has_previous()) # 是否有上一页
print(page2.previous_page_number()) # 上一页的页码
#把book_list传到模板层
return render(request,"book_list.html",{
"book_list":book_list,
})

访问http://127.0.0.1:8000/app01/book_list/,调试输出

True
3
True
1

这两个报错

        # page=paginator.page(22)   # error:EmptyPage
# page=paginator.page("z") # error:PageNotAnInteger

原因:

进入get_page查看源码

    def get_page(self, number):
"""
Return a valid page, even if the page argument isn't a number or isn't
in range.
"""
try:
number = self.validate_number(number)
except PageNotAnInteger:
number = 1 #非数字转为1
except EmptyPage:
number = self.num_pages #空转为最大页数
return self.page(number)

使用get就不会报错

views文件

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#基本使用
#获取当前页
current_page = request.GET.get('page')
#获取当前页数据,同时在html中循环
page = paginator.get_page(current_page) #把book_list传到模板层
return render(request,"book_list.html",{
#"book_list":book_list,
"page": page
})

html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>图书列表</h3>
<ul>
{% for book in page %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
</body>
</html>

访问http://127.0.0.1:8000/app01/book_list/,为空,显示第一页

访问http://127.0.0.1:8000/app01/book_list/?page=4,显示第四页

3 添加分页器

使用bootstrap做分页器显示

静态文件配置

root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir statics

root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir statics/css statics/js statics/images statics/plugins

root@darren-virtual-machine:~/PycharmProjects/cbv_test# ll statics/plugins/

drwxr-xr-x 5 root root 4096 4月  11 08:38 bootstrap-3.4.1-dist/

注册静态文件

STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"statics"),
]

html添加样式

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<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">&laquo;</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">&raquo;</span>
</a>
</li>
</ul>
</nav>
</body>
</html>

访问http://127.0.0.1:8000/app01/book_list/如下

下面应该可以显示所有的页面,使用一个for循环

views,把页数传递到html

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#基本使用
#获取当前页
current_page = request.GET.get('page')
#获取当前页数据,同时在html中循环
page = paginator.get_page(current_page) #把book_list传到模板层
return render(request,"book_list.html",{
#"book_list":book_list,
"page": page,
"paginator" :paginator
})

html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<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">&laquo;</span>
</a>
</li>
{% for num in paginator.page_range %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endfor %}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>
</body>
</html>

访问显示

4 分页器添加上一页和下一页代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<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="?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a> {% endif %} {% for num in paginator.page_range %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endfor %}
{% if page.has_next %}
<li>
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li> {% endif %} </ul>
</nav>
</body>
</html>

访问效果

5 分页器添加首页和尾页

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<ul>
{% for book in page %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="?page=1">首页</a></li>
{% if page.has_previous %}
<li>
<a href="?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a> {% endif %} {% for num in paginator.page_range %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endfor %}
{% if page.has_next %}
<li>
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li> {% endif %}
<li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
</ul>
</nav>
</body>
</html>

访问效果

6 分页器添加当前页标记

views文件传递参数

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 10)
#基本使用
#获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
current_page = int(request.GET.get('page',1))
#获取当前页数据,同时在html中循环
page = paginator.get_page(current_page) #把book_list传到模板层
return render(request,"book_list.html",{
#"book_list":book_list,
"page": page,
"paginator" :paginator,
"current_page": current_page
})

html文件配置

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<ul>
{% for book in page %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="?page=1">首页</a></li>
{% if page.has_previous %}
<li>
<a href="?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a> {% endif %} {% for num in paginator.page_range %}
{% if num == current_page %}
<li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
{% else %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li> {% endif %}
<li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
</ul>
</nav>
</body>
</html>

当有50页显示时,例如将每页显示2

 paginator = Paginator(book_list, 2)

显示如下

7 显示改进

views文件

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time
from django.utils.decorators import method_decorator # Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
@method_decorator(timer,name="get")
class Login(View):
#@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
obj = super().dispatch(request,*args,**kwargs)
return obj #这里必须返回,否则Httpresponse错误
#@method_decorator(timer)
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html") #分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
paginator = Paginator(book_list, 2)
#基本使用
#获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
current_page = int(request.GET.get('page',1))
#获取当前页数据,同时在html中循环
page = paginator.get_page(current_page)
# 我们按照页面显示11个页码为例。
# 如果总页码大于11
if paginator.num_pages > 11:
if current_page - 5 < 1: # 当前页小于中间页码时
page_range = range(1, 12)
elif current_page + 5 > paginator.num_pages: # 当前页大于中间页码时
page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
else:
page_range = range(current_page - 5, current_page + 6)
else:
page_range = paginator.page_range
#把book_list传到模板层
return render(request,"book_list.html",{
#"book_list":book_list,
"page": page,
"paginator" :paginator,
"current_page": current_page,
"page_range": page_range
})

html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>图书列表</h3>
<ul>
{% for book in page %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="?page=1">首页</a></li>
{% if page.has_previous %}
<li>
<a href="?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a> {% endif %} {% for num in page_range %}
{% if num == current_page %}
<li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
{% else %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0)" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li> {% endif %}
<li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
</ul>
</nav>
</body>
</html>

效果如下,前面

中间

最后

保证每页显示11个

8 自定制分页器

root@darren-virtual-machine:~/PycharmProjects/cbv_test# vim app01/utils.py

class Paginator:
def __init__(self, current_page, all_count, per_page=10, max_page_num=11):
"""
封装分页相关数据
:param current_page: 当前页码
:param all_count: 数据库中的数据总条数
:param per_page: 每个页面显示的数据条数
:param max_page_num: 最多显示的页码个数
:param num_pages: 通过总条数/每个页面显示的条数,求出总页数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page = per_page # 计算总页数
num_pages, temp = divmod(all_count, per_page)
if temp:
num_pages += 1
self.num_pages = num_pages self.max_page_num = max_page_num # 11
self.page_count_half = int((self.max_page_num - 1) / 2) # 5
"""
self.num_pages=100
per_page=8 current_page =1 [0:8]
current_page =2 [8:16]
current_page =3 [16:24]
[(current_page-1)*per_page:current_page*per_page ] """ @property
def start(self):
return (self.current_page - 1) * self.per_page @property
def end(self):
return self.current_page * self.per_page def page_html(self):
# 如果总页数小于self.max_page_num(最多显示的页码个数)
if self.num_pages <= self.max_page_num:
page_start = 1
page_end = self.num_pages + 1
else:
# 如果当前页码<=页面上最多显示11/2个页码时
if self.current_page <= self.page_count_half:
page_start = 1
page_end = self.max_page_num + 1
# 如果当前页码+最多显示11/2 大于 总页数时
elif self.current_page + self.page_count_half > self.num_pages:
page_start = self.num_pages - self.max_page_num + 1
page_end = self.num_pages + 1
else:
page_start = self.current_page - self.page_count_half
page_end = self.current_page + self.page_count_half + 1 page_html_list = [] # 首页
first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=1">首页</a></li>'
page_html_list.append(first_page) # 上一页
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1, )
page_html_list.append(prev_page) # 显示页码
for i in range(page_start, page_end):
if self.current_page == i:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
page_html_list.append(temp) # 下一页
if self.current_page >= self.num_pages:
next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1)
page_html_list.append(next_page) # 尾页
last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % self.num_pages
page_html_list.append(last_page) return "".join(page_html_list)

视图调用

#分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
#为了避免重复,取得别名
from app01.utils import Paginator as MyPaginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
#paginator = Paginator(book_list, 2)
#基本使用
#获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
current_page = int(request.GET.get('page',1))
#获取当前页数据,同时在html中循环
#page = paginator.get_page(current_page)
# 我们按照页面显示11个页码为例。
# 如果总页码大于11
#if paginator.num_pages > 11:
# if current_page - 5 < 1: # 当前页小于中间页码时
# page_range = range(1, 12)
# elif current_page + 5 > paginator.num_pages: # 当前页大于中间页码时
# page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
# else:
# page_range = range(current_page - 5, current_page + 6)
#else:
# page_range = paginator.page_range
paginator = MyPaginator(current_page, book_list.count(), 8, 11)
book_list = book_list[paginator.start:paginator.end]
#把book_list传到模板层
#return render(request,"book_list.html",{
return render(request, "book_list1.html", {
"book_list":book_list,
#"page": page,
"paginator" :paginator,
"current_page": current_page,
#"page_range": page_range,
#"book_list":book_list,
})

book_list1.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
</head>
<body>
<h3>书籍列表!!!</h3> <ul>
{% for book in book_list %}
<li>{{ book.title }}---价格---{{ book.price }}</li>
{% endfor %}
</ul>
{{ paginator.page_html|safe }}
</body>
</html>

结果

9 带参数分页器调用

如果需要携带参数

utils文件

class Paginator:
def __init__(self, request, current_page, all_count, per_page=10, max_page_num=11):
"""
封装分页相关数据
:param current_page: 当前页码
:param all_count: 数据库中的数据总条数
:param per_page: 每个页面显示的数据条数
:param max_page_num: 最多显示的页码个数
:param num_pages: 通过总条数/每个页面显示的条数,求出总页数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page = per_page # 计算总页数
num_pages, temp = divmod(all_count, per_page)
if temp:
num_pages += 1
self.num_pages = num_pages self.max_page_num = max_page_num # 11
self.page_count_half = int((self.max_page_num - 1) / 2) # 5 import copy
self.url_args = copy.deepcopy(request.GET)
print(self.url_args.urlencode())
"""
self.num_pages=100
per_page=8 current_page =1 [0:8]
current_page =2 [8:16]
current_page =3 [16:24]
[(current_page-1)*per_page:current_page*per_page ] """ @property
def start(self):
return (self.current_page - 1) * self.per_page @property
def end(self):
return self.current_page * self.per_page def page_html(self):
# 如果总页数小于self.max_page_num(最多显示的页码个数)
if self.num_pages <= self.max_page_num:
page_start = 1
page_end = self.num_pages + 1
else:
# 如果当前页码<=页面上最多显示11/2个页码时
if self.current_page <= self.page_count_half:
page_start = 1
page_end = self.max_page_num + 1
# 如果当前页码+最多显示11/2 大于 总页数时
elif self.current_page + self.page_count_half > self.num_pages:
page_start = self.num_pages - self.max_page_num + 1
page_end = self.num_pages + 1
else:
page_start = self.current_page - self.page_count_half
page_end = self.current_page + self.page_count_half + 1 page_html_list = [] # 首页
self.url_args['page'] = 1
#first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=1">首页</a></li>'
first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=%s">首页</a></li>' % self.url_args.urlencode()
page_html_list.append(first_page) # 上一页
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
else:
self.url_args['page'] = self.current_page - 1
#prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1, )
prev_page = '<li><a href="?%s">上一页</a></li>' % self.url_args.urlencode()
page_html_list.append(prev_page) # 显示页码
for i in range(page_start, page_end):
self.url_args['page'] = i
if self.current_page == i:
#temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
else:
#temp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
temp = '<li><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
page_html_list.append(temp) # 下一页
if self.current_page >= self.num_pages:
next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
else:
self.url_args['page'] = self.current_page + 1
#next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1)
next_page = '<li><a href="?%s">下一页</a></li>' % self.url_args.urlencode()
page_html_list.append(next_page) # 尾页
self.url_args['page'] = self.num_pages
#last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % self.num_pages
last_page = '<li><a href="?%s">尾页</a></li></ul></nav>' % self.url_args.urlencode()
page_html_list.append(last_page) return "".join(page_html_list)

视图文件

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time
from django.utils.decorators import method_decorator # Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
@method_decorator(timer,name="get")
class Login(View):
#@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
obj = super().dispatch(request,*args,**kwargs)
return obj #这里必须返回,否则Httpresponse错误
#@method_decorator(timer)
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html") #分页器
from app01.models import Book
#from app01 import models
import random
from django.core.paginator import Paginator
#为了避免重复,取得别名
from app01.utils import Paginator as MyPaginator
class Booklist(View):
def get(self,request):
book_list = Book.objects.all()
#分页器的基本语法
# 实例化分页器对象
#paginator = Paginator(book_list, 2)
#基本使用
#获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
current_page = int(request.GET.get('page',1))
#获取当前页数据,同时在html中循环
#page = paginator.get_page(current_page)
# 我们按照页面显示11个页码为例。
# 如果总页码大于11
#if paginator.num_pages > 11:
# if current_page - 5 < 1: # 当前页小于中间页码时
# page_range = range(1, 12)
# elif current_page + 5 > paginator.num_pages: # 当前页大于中间页码时
# page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
# else:
# page_range = range(current_page - 5, current_page + 6)
#else:
# page_range = paginator.page_range
paginator = MyPaginator(request,current_page, book_list.count(), 8, 11)
book_list = book_list[paginator.start:paginator.end]
#把book_list传到模板层
#return render(request,"book_list.html",{
return render(request, "book_list1.html", {
"book_list":book_list,
#"page": page,
"paginator" :paginator,
"current_page": current_page,
#"page_range": page_range,
#"book_list":book_list,
})

访问http://127.0.0.1:8000/app01/book_list/?page=10&name=joy&password=123结果如下

当代有参数时,把鼠标放在不分页器上,最下面可以显示到后面页带的有参数


参考文档:https://www.cnblogs.com/Michael--chen/p/10965465.html

老男孩教育视频:https://www.oldboyedu.com/

063.Python前端Django分页器的更多相关文章

  1. 058.Python前端Django与Ajax

    一 Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是"异步Javascript和XML".即使用Javascript语言与服务 ...

  2. 055.Python前端Django模型ORM

    由于前面在centos实验的过程中,pymql一直有属性错误,很难排查出问题,重新做了一个ubuntu的桌面系统同时使用pycharm开发工具作为学习开发工具,具体原因是因为在项目命名出现问题,和自己 ...

  3. 052.Python前端Django框架路由层和视图层

    一.路由层(URLconf) 1.1 路由层简单配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Dj ...

  4. 061.Python前端Django组件用户认证组件

    一 auth认证组件 在使用pymysql,数据库迁移的时候.,默认生成有十张表如下 查看author_user表结构 mysql> desc auth_user; +------------- ...

  5. 059.Python前端Django组件cooki和session

    一 会话跟踪技术 1.1 什么是会话 会话是指一个终端用户(服务器)与交互系统(客户端)进行通讯的过程. 1.2 什么是会话跟踪 对同一个用户对服务器的连续的请求和接受响应的监视.(将用户与同一用户发 ...

  6. 057.Python前端Django模型ORM多表查询

    一 基于对象的查询 1.1 一对多查询 设计路由 from django.contrib import admin from django.urls import path from app01 im ...

  7. 056.Python前端Django模型ORM多表基本操作

    一 准备工作 1.1 新建一个项目 root@darren-virtual-machine:~# cd /root/PycharmProjects/ root@darren-virtual-machi ...

  8. 053.Python前端Django框架模板层

    模板层 一 模板语法之变量 在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法: {{ var_name }} [root@node10 mysite]# cat app01/urls. ...

  9. [Python] 利用Django进行Web开发系列(一)

    1 写在前面 在没有接触互联网这个行业的时候,我就一直很好奇网站是怎么构建的.现在虽然从事互联网相关的工作,但是也一直没有接触过Web开发之类的东西,但是兴趣终归还是要有的,而且是需要自己动手去实践的 ...

随机推荐

  1. 考前自救题库NABCD分析

    考前自救题库NABCD分析 项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-初次邂逅,需求分析 项目名称:考前自救题库(暂定) 项目简介:本产品计 ...

  2. Day07_36_Iterator迭代器

    Iterator Iterator Iterator iterator(); 获取集合所依赖的迭代对象 通过迭代器iterator()中的方法完成集合的迭代(遍历),这种方式是所有集合通用的遍历方法. ...

  3. linux gcc命令参数

    gcc命令参数笔记 1. gcc -E source_file.c -E,只执行到预处理.直接输出预处理结果. 2. gcc -S source_file.c -S,只执行到汇编,输出汇编代码. 3. ...

  4. OO第四单元总结与课程总结

    OO第四单元总结与课程总结 第四单元作业架构设计 总体分析:本单元作业的需求集中于对UML类图进行查询.对于查询操作来说自然的想法是提前预见到需要查询的内容,在一开始就采用适当的数据结构将必要的信息进 ...

  5. MySQL8安装教程及问题解决

    目录 1.下载MySQL的zip文件,解压,在根目录(bin所在的目录)下创建my.ini文件 2.管理员模式打开命令提示符(shell或者说小黑窗),按以下命令操作. 3.不过......我这里密码 ...

  6. 1053 Path of Equal Weight

    Given a non-empty tree with root R, and with weight W​i​​ assigned to each tree node T​i​​. The weig ...

  7. 展开说说,Spring Bean IOC、AOP 循环依赖

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 延迟满足能给你带来什么? 大学有四年时间,但几乎所有人都是临近毕业才发现找一份好工作 ...

  8. 关于Snowflake 生成53位ID

    1, bug现象: 没有经过处理的Snowflake 生成的是64位bit的唯一ID,但由于多数时候我们前台用到js,但是js只支持53位bit的数值.这样就导致了传到前台的64位的丢失精度. 解决思 ...

  9. 【Java注解】@PostConstruct 注解相关

    不多逼逼,直接看注解上面的文档, @PostConsturct PostConstruct注释用于需要执行的方法在依赖注入完成后执行任何初始化.这个方法必须在类投入服务之前调用. 这个所有支持依赖关系 ...

  10. 从苏宁电器到卡巴斯基第15篇:我在苏宁电器当营业员 VII

    我们苹果的倒班制度 当年我在苏宁的时候,实行的是单休制度,而且只能选择在周一到周五其中的某一天,因为周六周日顾客比较多,是不允许休息的.尽管是单休,但并不表示我们在上班的时候每天都要完完整整地上八小时 ...