一、分页的逻辑与处理规则
通过从数据库中提取数据的形式分析如何分页
queryset = models.PrettyNum.objects.all() # 提取数据库中该表中的所有数据
queryset = models.PrettyNum.objects.filter(id=1)[0:10] # 提取数据库中前十条数据
# 第1页
queryset = models.PrettyNum.objects.all()[0:10]
# 第2页
queryset = models.PrettyNum.objects.all()[10:20]
# 第3页
queryset = models.PrettyNum.objects.all()[20:30]
data = models.PrettyNum.objects.all().count()
data = models.PrettyNum.objects.filter(id=1).count()
分页的逻辑和处理规则
from django.forms import ModelForm
from django.shortcuts import render, HttpResponse, redirect
import app01.models
from app01 import models
from django.forms import ModelForm
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe
def pretty_list(request):
"""靓号列表"""
# 添加数据循环加入300条一样的数据
# for i in range(300):
# models.PrettyNum.objects.create(mobile="18530123456", price=20, level=2, status=1)
data_dict = {}
search_data = request.GET.get('q', "")
if search_data:
data_dict["mobile__contains"] = search_data
# res = models.PrettyNum.objects.filter(**data_dict)
# 1.根据用户想要访问的页码,计算出起止位置
page = int(request.GET.get("page", 1))
page_size = 10 # 每页显示10条数据
start = (page - 1) * page_size
end = page * page_size
# select *from 表 order by level desc;
queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")[start:end]
# 数据总条数
total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-level").count()
# 总页码
total_page_count, div = divmod(total_count, page_size)
if div:
total_page_count += 1
# 计算出,显示当前页的前5页、后5页
plus = 5
if total_page_count <= 2 * plus+1:
# 数据库中数量比较少,都没有达到11页
start_page = 1
end_page = total_page_count
else:
# 数据库中的数据比较多>11页
# 当前页<5时(小极值)
if page <= plus:
start_page = 1
end_page = 2 * plus + 1
else:
# 当前页>5
# 当前页+5 > 总页面
if (page + plus) > total_page_count:
start_page = total_page_count - 2 * plus
end_page = total_page_count
else:
start_page = page - plus
end_page = page + plus
# 页码
page_str_list = []
# 首页
page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))
# 上一页
if page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(page - 1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
# 页面
for i in range(start_page, end_page + 1):
if i == page:
ele = '<li class="active" ><a href="?page={}">{}</a></li>'.format(i, i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
# 下一页
if page < total_page_count:
prev = '<li><a href="?page={}">下一页</a></li>'.format(page + 1)
else:
prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
page_str_list.append(prev)
# 尾页
page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))
search_string = """
<li style="float: right;">
<form method="get">
<div class="input-group" style="width:118px;border-radius: 0;">
<input type="text" name="page" class="form-control" placeholder="页码" style="border-radius: 0;">
<span class="input-group-btn">
<button class="btn btn-default" type="submit" style="color:#337AB7">跳转</button>
</span>
</div>
</form>
</li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return render(request, "pretty_list.html", {"queryset": queryset, "search_data": search_data, "page_string": page_string})
在要分页的html中添加以下代码:
<ul class="pagination">
{{ page_string }}
</ul>
二、封装分页类
在 app 目录下创建一个新文件夹 utils 文件夹
在 utils 目录下创建 pagination.py 文件( 写项目用【pagination.py】公共组件)。
"""
自定义的分页组件,以后如果想要使用这个分页组件,你需要做如下几件事:
在视图函数中(views.py):
from app01.utils.pagination import Pagination
def pretty_list(request):
# 1.根据自己的情况去筛选自己的数据
queryset = models.PrettyNum.objects.all()
# 2.实例化分页对象
page_object = Pagination(request, queryset)
context = {
"search_data": search_data,
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html(), # 生成页码
}
return render(request, "pretty_list.html", context)
在html页面中:
{% for obj in queryset %}
{{ obj.xxx }}
{% endfor %}
<ul class="pagination">
{{ page_string }}
</ul>
"""
from django.utils.safestring import mark_safe
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):
"""
:param request: 请求的对象
:param queryset: 符合条件的数据(根据这个数据给他进行分页处理)
:param page_size: 每页显示多少条数据
:param page_param: 在URL中传递的获取分页的参数,例如:/etty/list/?page=12
:param plus: 显示当前页的前几页或后几页(页码)
"""
from django.http.request import QueryDict
import copy
query_dict = copy.deepcopy(request.GET)
query_dict._mutable = True
self.query_dict = query_dict
self.page_param = page_param
page = request.GET.get(page_param, "1")
if page.isdecimal():
page = int(page)
else:
page = 1
self.page = page
self.page_size = page_size
self.start = (page - 1) * page_size
self.end = page * page_size
self.page_queryset = queryset[self.start:self.end]
# 数据总条数
total_count = queryset.count()
# 总页码
total_page_count, div = divmod(total_count, page_size)
if div:
total_page_count += 1
self.total_page_count = total_page_count
self.plus = plus
def html(self):
# 计算出,显示当前页的前5页、后5页
if self.total_page_count <= 2 * self.plus + 1:
# 数据库中数量比较少,都没有达到11页
start_page = 1
end_page = self.total_page_count
else:
# 数据库中的数据比较多>11页
# 当前页<5时(小极值)
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
# 当前页>5
# 当前页+5 > 总页面
if (self.page + self.plus) > self.total_page_count:
start_page = self.total_page_count - 2 * self.plus
end_page = self.total_page_count
else:
start_page = self.page - self.plus
end_page = self.page + self.plus
# 页码
page_str_list = []
# 首页
self.query_dict.setlist(self.page_param, [1])
page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
# 上一页
if self.page > 1:
self.query_dict.setlist(self.page_param, [self.page - 1])
prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [1])
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
# 页面
for i in range(start_page, end_page + 1):
self.query_dict.setlist(self.page_param, [i])
if i == self.page:
ele = '<li class="active" ><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
else:
ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
page_str_list.append(ele)
# 下一页
if self.page < self.total_page_count:
self.query_dict.setlist(self.page_param, [self.page + 1])
prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [self.total_page_count])
prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
# 尾页
self.query_dict.setlist(self.page_param, [self.total_page_count])
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
search_string = """
<li style="float: right;">
<form method="get">
<div class="input-group" style="width:118px;border-radius: 0;">
<input type="text" name="page" class="form-control" placeholder="页码" style="border-radius: 0;">
<span class="input-group-btn">
<button class="btn btn-default" type="submit" style="color:#337AB7">跳转</button>
</span>
</div>
</form>
</li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return page_string
from app01.utils.pagination import Pagination
def depart_list(request):
"""部门列表"""
# 去数据库中获取所有的部门名称
queryset = models.Department.objects.all()
page_object = Pagination(request, queryset, page_size=2) # 每页显示几条(page_size=2)
context = {
"queryset": page_object.page_queryset,
"page_string": page_object.html(),
}
# print(queryset)
return render(request, "depart_list.html", context)
<ul class="pagination" style="position: absolute;transform: translate(50%);">
{# style="position: absolute;transform: translate(50%);" 居中设置 根据实际情况改动 #}
{{ page_string }}
</ul>