完成结果如下:
1.手动分页
视图view.py修改成如下:
def students(request): section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip() if search: if search.isdigit(): sts = Student.objects.filter(Q(qq=search)|Q(phone=search),is_deleted=False).order_by('-e_time') #是qq或者电话 else: sts = Student.objects.filter(name__contains=search,is_deleted=False).order_by('-e_time') else: sts = Student.objects.filter(is_deleted=False).order_by('-e_time') #当前页 page = request.GET.get('page',1) page = int(page) #每页显示多少数据 per_page = request.GET.get('per_page',10) per_page = int(per_page) total_num = sts.count() #总学生数 sts = sts[(page-1)*per_page:page*per_page] return render(request,'teacher/students.html',context= {'students':sts, 'section':section, 'search':search, 'per_page':per_page, 'page':page, 'total_num':total_num })
students.html修改如下:(只显示了修改部分的代码)
....
{% load customer_tags %} #引用自定义的标签 .... </div> <div class="btn-group" role="group"> <div class="btn-group" role="group"> <nav aria-label="Page navigation"> {% pagination_html %} </nav> </div> <div class="btn-group" role="group"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ per_page }}条/页<span class="caret"></span> </button> <ul class="dropdown-menu"> <li><a href="{{ request.path }}?search={{ search }}&per_page=5">5条/页</a></li> <li><a href="{{ request.path }}?search={{ search }}&per_page=10">10条/页</a></li> <li><a href="{{ request.path }}?search={{ search }}&per_page=20">20条/页</a></li> </ul> </div>
自定义标签customer_tag.py
@register.inclusion_tag('teacher/pagination.html',takes_context=True) #takes_context=True 能够取到在views中所有的context的上下文 def pagination_html(context): num = 3 #总共显示多少个页码 page_num = context['page'] per_page = context['per_page'] students = context['students'] #总学生数 total_num = context['total_num'] #总页数 total_page = math.ceil(total_num/per_page) #页码列表 page_list=[] #生成当前页,以及左边的页数 if page_num - (num-1)//2 <=0: #说明左边的页数应该从1开始 for i in range(page_num): page_list.append(i+1) else: #左边的页数应该从 page_num -(num-1)//2开始 for i in range(page_num-(num-1)//2,page_num+1): page_list.append(i) #生成右边的页数 if page_num + (num-1)//2 >= total_page: for i in range(page_num+1,total_page+1): page_list.append(i) else: for i in range(page_num+1,page_num+(num-1)//2+1): page_list.append(i) return { 'page_num_list':page_list, 'page_num':page_num, 'context':context, 'total_page':total_page }
自定义标签中需要渲染的页面
<ul class="pagination" style="margin: 0px"> <li {% if page_num == 1 %}class="disabled" {% endif %}> <a href="{{ request.path }}?search = {{ context.search }}&page={{ page_num|add:'-1' }}&per_page={{ context.per_page }}" aria-label="Previous"> <span aria-hidden="true">上一页</span> </a> </li> {% for num in page_num_list %} <li {% if num == page_num %}class="active"{% endif %}><a href="{{ request.path }}?search={{ context.search }}&page={{ num }}&per_page={{ context.per_page }}">{{ num }}</a></li> {% endfor %} <li {% if page_num == total_page %}class="disabled" {% endif %}> <a href="{{ request.path }}?search = {{ context.search }}&page={{ page_num|add:'1' }}&per_page={{ context.per_page }}" aria-label="Next"> <span aria-hidden="true">下一页</span> </a> </li> </ul>
2.内置分页需要的引用的库
Paginator
引用导入
In [1]: from teacher.models import Student In [2]: from django.core.paginator import Paginator
必须要在排序的基础上分页,进行实例化,前面的参数是可迭代对象,第二个参数为per_page,每页显示的数据,必须是整数
In [3]: p = Paginator(Student.objects.all().order_by('-c_time'),3)
查看实例的成员个数
In [5]: p.count Out[5]: 16 In [6]: Student.objects.all().count() Out[6]: 16
返回总页数
In [7]: p.num_pages
Out[7]: 6
页面范围
In [8]: p.page_range
Out[8]: range(1, 7)
通过索引的方式,基于1的数据
In [9]: page1 = p.page(1) In [10]: page1.object_list Out[10]: <QuerySet [<Student: 22-缇子-23>, <Student: 21-李涛-12>, <Student: 20-小泼-22>]>
查看是否有上一页,是否有下一页
In [11]: page1.has_previous() Out[11]: False In [12]: page1.has_next() Out[12]: True
返回下一页的页码
In [13]: page1.next_page_number() Out[13]: 2
下面的实例操作根据内置分页工具修改了部分代码。
2.内置分页
view.py(比较前面代码,修改如下)
from django.core.paginator import Paginator
def students(request):.... paginator = Paginator(sts,per_page) sts = paginator.get_page(page) #当前页 return render(request,'teacher/students.html',context= { 'students':sts, 'section':section, 'search':search, 'per_page':per_page, 'page':page, })
customer_tags.py的修改如下:
@register.inclusion_tag('teacher/pagination.html',takes_context=True) #能够取到在views中所有的context的上下文 def pagination_html(context):
.... num = 3 #总共显示多少个页码 page_num = context['page'] per_page = context['per_page'] # students = context['students'] #总学生数 total_num = context['students'].paginator.count #总页数 total_page = context['students'].paginator.num_pages #页码列表
....