(1)首先在settings.py同目录下建立pagination.py文件:
# -*- coding: utf-8 -*- from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # 分页 import re # 正则 # 下面是逻辑分页代码,配合模板的 {{ forloop.counter | add:xuhao }} 使用,达到分页后每行的序号按步长为1递增 def web_pagination(list, single, remainder, page,): # 参数分别为数据列表,单页展示行数,不足x行时并入上一页,当前页码 paginator = Paginator(list, single, remainder) try: # try及其以下是判断page传入值 contacts = paginator.page(page) except PageNotAnInteger: # # 当page为非数字时,默认显示第一页 contacts = paginator.page(1) except EmptyPage: # 当page小于1或大于实际页数,默认显示最后一页 contacts = paginator.page(paginator.num_pages) if page: # 判断page是否存在,if及其以下主要是分别序号递增 if re.match(r'[+-]?\d+$', page): # 匹配page是数字,避免其他字符页面报错 if int(page) > contacts.paginator.num_pages or int(page) < 1: # 当page小于1或大于实际页数,默认显示实际最后一页 xuhao = single * (contacts.paginator.num_pages - 1) else: xuhao = single * (int(page) - 1) # 第 page-1 页的序号要加上的数值 else: # 当page为none时,默认显示实际第一页 xuhao = 0 else: # 当page为非数字时,默认显示第一页 xuhao = 0 return (contacts ,xuhao)
(2)其次,在任一APP目录下(由于Django规定自定义标签只能在APP下进行注册使用,防止其他Django程序使用,因此在任一APP下都创建,其他APP可以串用)创建templatetags文件夹,建立__init__.py、paginglabel.py:
# -*- coding: utf-8 -*- from django import template from django.utils.html import format_html register = template.Library() # 模板库支持 page_display = 8 # 超过8页时,始终显示8个可选页码按钮; @register.simple_tag def circle_page(curr_page, loop_page, bigest_page): # 当前页码、循环页码、总页码数 offset = curr_page - loop_page # 计算当前页码与 循环到的页数 差值 if ((offset < page_display and offset >= 0) or (curr_page <= page_display and loop_page <= page_display)) and bigest_page > 1: # 只有一页时不显示页码标签 if curr_page == loop_page: page_ele = '<li class="active"><a href="?page=%s">%s</a></li>' % (loop_page,loop_page) else: page_ele = '<li><a href="?page=%s">%s</a></li>' % (loop_page,loop_page) return format_html(page_ele) else: return '' @register.simple_tag def goto_page(list): # 输入页码直接跳转到指定页 if list.paginator.num_pages > page_display: # 当整个页码数小于等于 page_display 页时,跳转功能隐藏 page_ele = '<li> \ <div style="float:left;"> \ <input type="text" class="form-control" style="width:82px" placeholder="输入页码" id="page"> \ </div> \ <div style="float:right;"> \ <input type="botton" class="btn btn-primary" style="width:60px;BACKGROUND-COLOR:green" onclick ="submit()" value ="跳转"> \ </div> \ </li>' return format_html(page_ele) else: return '' @register.simple_tag def last_page(list): # 上一页、首页功能按钮 if list.has_previous(): # 当到达第一页时,隐藏上一页、首页功能按钮 page_ele = '<li><a href="?page=1">首页</a></li> \ <li><a href="?page=%s" aria-label="Previous">上一页</a></li>' % (list.previous_page_number()) return format_html(page_ele) else: return '' @register.simple_tag def next_page(list): # 下一页、尾页功能按钮 if list.has_next(): # 当到达最后一页时,隐藏下一页、尾页功能按钮 page_ele = '<li><a href="?page=%s" aria-label="Next">下一页</a></li> \ <li><a href="?page=%s">尾页</a></li>' % (list.next_page_number(),list.paginator.num_pages) return format_html(page_ele) else: return '' @register.simple_tag def total_page(list): # 共计多少页 if list.paginator.num_pages > 1: # 只有一页时不显示 page_ele = '<li><a><b style="color:black">共 %s 页</b></a></li>' % (list.paginator.num_pages) return format_html(page_ele) else: return ''
【注】:__init__.py为空白文件。
(3)接着修改APP对应的views.py文件(红色加粗表示为了分页添加的):
def testrecord_list(request): data_list = TestRecord.objects.filter(web_display=1) ConXu = web_pagination(data_list, 15, 3, request.GET.get('page')) # 分页 return render(request,'testrecord_list.html', {'contacts': ConXu[0],'xuhao':ConXu[1]})
【注】:其中数字15、3分别代表 单页展示数据15行、单页不足3行时并入上一页
(4)最后在需要分页的APP模板html文件中引入分页(红色加粗表示为了分页添加、修改的):
pagination.css:
.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#59bcdb;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#59bcdb;border-color:#59bcdb}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}
list.html:
{% extends "base.html" %} {% block text %} <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}测试管理 | 测试记录列表{% endblock %}</title> <link rel="stylesheet" href="/media/index/css/pagination.css" /> </head> <body> <div class="col-xs-0 col-sm-0 placeholder"> <h2 class="sub-header"> <img src="/media/logo/testrecord.jpg" width="50" height="50" alt="哎呀,图片不见啦!"> 测试记录 </h2> </div> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>序号</th> <th>BUG简称</th> <th>所属项目</th> <th>所属模块</th> <th>BUG等级</th> <th>当前状态</th> <th>测试结果</th> <th>更新时间</th> </tr> </thead> <tbody> {% for name in contacts %} <tr> <td>{{ forloop.counter | add:xuhao }}</td> <td><a href="{{ name.get_url }}">{{ name.bug_name }}</a></td> <td>{{ name.project_name }}</td> <td>{{ name.module_name }}</td> <td>{{ name.bug_level }}</td> <td>{{ name.current_state }}</td> <td> {% if name.get_test_result_display %} <b style="color:green">{{ name.get_test_result_display }}</b> {% else %} <b style="color:red">待修复</b> {% endif %} </td> <td>{{ name.update_time }}</td> </tr> {% endfor %} </tbody> </table> </div> <div align="center"> {% load paginglabel %} <nav aria-label="Page navigation"> <ul class="pagination"> {% last_page contacts %} {% for pg in contacts.paginator.page_range %} {% circle_page contacts.number pg contacts.paginator.num_pages %} {% endfor %} {% next_page contacts %} {% total_page contacts %} <script> function submit() { var input = document.getElementById("page"); window.location.href="?page=" + input.value; } </script> {% goto_page contacts %} </ul> </nav> </div> </body> </html> {% endblock%}
(5)最终的效果图:
① 只有一页时:
② 超过一页,不足8页时:
③ 超过8页时: