分页有固定步骤,无脑按要求执行即可。
自定义的分页组件,以后如果想要使用这个分页组件,你需要做如下几件事:在视图函数中:
def pretty_list(request):# 1.根据自己的情况去筛选自己的数据
queryset = models.PrettyNum.objects.all()# 2.实例化分页对象
page_object = Pagination(request, queryset)context = {
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 生成页码
}
return render(request, 'pretty_list.html', context)
在HTML页面中
{% for obj in queryset %}
{{obj.xx}}
{% endfor %}
<ul class="pagination">
{{ page_string }}
</ul>
首先,我们在utils文件夹下,创建pagination.py
编写分页业务逻辑,不用管,直接拿来用就行。
# 导入Django的工具类,用于标记安全字符串
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: 显示当前页的 前或后几页(页码)"""# 深拷贝请求的GET参数,用于后续生成URLfrom django.http.request import QueryDictimport copyquery_dict = copy.deepcopy(request.GET)query_dict._mutable = Trueself.query_dict = query_dict# 分页参数的名称self.page_param = page_param# 获取当前页码,默认为第1页page = request.GET.get(page_param, "1")# 确保页码为整数if page.isdecimal():page = int(page)else:page = 1# 当前页码和每页显示的数据条数self.page = pageself.page_size = page_size# 计算数据切片的起止位置self.start = (page - 1) * page_sizeself.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 += 1self.total_page_count = total_page_count# 显示当前页的前后页数self.plus = plus# 生成HTML页码的方法def html(self):# 计算出,显示当前页的前5页、后5页if self.total_page_count <= 2 * self.plus + 1:# 数据库中的数据比较少,都没有达到11页。start_page = 1end_page = self.total_page_countelse:# 数据库中的数据比较多 > 11页。# 当前页<5时(小极值)if self.page <= self.plus:start_page = 1end_page = 2 * self.plus + 1else:# 当前页 > 5# 当前页+5 > 总页面if (self.page + self.plus) > self.total_page_count:start_page = self.total_page_count - 2 * self.plusend_page = self.total_page_countelse:start_page = self.page - self.plusend_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="?{}">上一页</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><form style="float: left;margin-left: -1px" method="get"><input name="page"style="position: relative;float:left;display: inline-block;width: 80px;border-radius: 0;"type="text" class="form-control" placeholder="页码"><button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button></form></li>"""page_str_list.append(search_string)# 将列表中的字符串拼接为安全的HTML字符串page_string = mark_safe("".join(page_str_list))return page_string
步骤1 导包
from app01.utils.pagination import Pagination
步骤2 编写业务逻辑,此处修改之前的dept_list业务逻辑
def dept_list(request):# 查询部门列表数据queryset = models.Dept.objects.using('default').all()# 创建分页对象page_obj = Pagination(request, queryset)# 把查询到的数据传递到前端# context = {# 'queryset': queryset# }context = {"queryset": page_obj.page_queryset,"page_html": page_obj.html(),}return render(request, 'dept_list.html', context)
步骤3 去dept_list.html添加分页结尾
{% extends 'base.html' %}{% block content %}<div class="container-fluid"><div style="margin-bottom: 10px" class="clearfix"><div class="panel panel-default"><!-- Default panel contents --><div class="panel-heading"><a class="btn btn-primary" href="/dept/add/" role="button">添加部门</a><!--因为涉及到提交以及数据路径拼接,所以需要一个form表单,method为get--><div style="float: right"><form class="form-inline" action="/dept/search/" method="get"><!--添加搜索框--><!--name=q 非常的重要--><input type="text" class="form-control" name="q" placeholder="请输入要搜索的部门"aria-label="Recipient's username" aria-describedby="button-addon2"><button class="btn btn-outline-secondary" type="submit" id="button-addon2">搜索</button></form></div></div><div class="panel-body"><div style="float: left"><p>部门列表</p></div><!-- Table --><table class="table"><thead><tr><th>ID</th><th>name</th><th>head</th><th>phone</th><th>email</th><th>address</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><td>{{ obj.id }}</td><td>{{ obj.name }}</td><td>{{ obj.head }}</td><td>{{ obj.phone }}</td><td>{{ obj.email }}</td><td>{{ obj.address }}</td><td><a class="btn btn-success" href="/dept/{{ obj.id }}/edit_detail/"role="button">编辑部门</a><a class="btn btn-danger" href="/dept/{{ obj.id }}/delete/" role="button">删除部门</a></td></tr>{% endfor %}</tbody></table>{% if error %}<div style="color: red;">{{ error }}</div>{% endif %}</div></div></div><!-- 加上分页 --><div class="row"><ul class="pagination">{{ page_html }}</ul></div></div>{% endblock %}
效果如下:

