分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该显示在页面上的数据在数据库表中的起始位置。
1. 每页显示的数据条数 2. 每页显示页号链接数 3. 上一页和下一页 4. 首页和末页
一、Django自带分页器
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger def index(request): #大批量插入数据 # booklist=[] # for i in range(100): # obj=models.Book(name='book %s'%i,price=30+i*2) # booklist.append(obj) # models.Book.objects.bulk_create(booklist) #-------Paginator类的使用 book_lists=models.Book.objects.all() # Paginator(分页对象,每1页显示X条目) # -------------------------分页对象的属性 p=Paginator(book_lists,10) #p.count s数据总条目 例 100 print(p.count) #p.num_pages 可以分多少页 5 print(p.num_pages) #page_range 页码列表 [1,2,3,4,5] print(p.page_range) #-------------------------------------------------- # 以上都是和Paginator总页数对象相关的内容,一下是和单页相关的内容 #第1页的page对象 page1=p.page(1) # 获取第1页所有数据 print(page1.object_list) #第2页page对象 page2 = p.page(2) #获取第2页所有数据 print(page2.object_list) # 可以单页的数据,就可以从前端传数据动态取第几页了! #-----------------------------------------------------------------
视图
page_number = request.GET.get("page") book_lists = models.Book.objects.all() p=Paginator(book_lists,20) try: book_list=p.page(page_number) #如果用户输入的页码超出 范围,显示末页 except EmptyPage: book_list=p.page(p.num_pages) #如果用户输入的页码是字符串等无效页码,显示第1页 except PageNotAnInteger: book_list=p.page(1) return render(request,'index.html',locals())
前端
<nav aria-label="Page navigation" style="position: fixed;bottom: 5px;right: 50%"> <ul class="pagination"> {% if book_list.has_previous %} <li><a href="/index/?page={{ book_list.previous_page_number }}">上页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">上页</a></li> {% endif %} {% for page in p.page_range %} <li><a href="/index/?page={{ page }}">{{ page }} <span class="sr-only">(current)</span></a></li> {% endfor %} {% if book_list.has_next %} <li><a href="/index/?page={{ book_list.next_page_number }}">下页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">下页</a></li> {% endif %} </ul> </nav>
[10/Oct/2018 09:22:10] "GET /favicon.ico HTTP/1.1" 200 12 /root/cmdb_rbac_arya/multitask/logs_handler.py:19: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'cmdb.models.Task'> QuerySet. p = Paginator(task_objects,5) [10/Oct/2018 09:22:23] "GET /multitask/task/ HTTP/1.1" 200 47420
出现以上报错是因为QuerySet无序导致,order_by('pk')即可。
二、自定制分页器
视图
class PageInfo(object): def __init__(self,current_page,all_count,per_page,show_page=11): try: #如果用户传入的页码异常 就让页码=1 self.current_page=int(current_page) except Exception: self.current_page = 1 self.show_page=show_page self.per_page=per_page a,b=divmod(all_count,per_page) #计算显示数据库一共需要 多少总页码 if b: a=a+1 self.all_page=a def start(self): return (self.current_page-1)* self.per_page def stop(self): return self.current_page*self.per_page def pager(self): #该方法专门用于 在前端显示页码 half=int((self.show_page-1)/2) #如数据库 数据条目 小于 11条 if self.all_page < self.show_page: begin=1 stop=self.all_page+1 else: #如果当前页小于=5 起始页再减去5就是负数了那么 就 显示0-11页码 if self.current_page<=half: begin =1 stop=self.show_page+1 else: begin=self.current_page-half stop=self.current_page+half+1 page_list = [] if self.current_page<=1: #如果当前页是1了就不要在上一页了 b = '<a href="/index?page=#">上一页</a>' else: b='<a href="/index?page=%s">上一页</a>'%(self.current_page-1) page_list.append(b) for i in range(begin,stop): if i ==self.current_page: temp='<a style="display: inline-block;padding: 5px;margin: 5px;background-color: bisque" href="/index?page=%s">%s</a>'%(i,i) else: temp = '<a style="display: inline-block;padding: 5px;margin: 5px;href="/index?page=%s">%s</a>'% (i,i) page_list.append(temp) if self.current_page >= self.all_page: nex = "<li><a href='#'>下一页</a></li>" else: nex ='<a href="/index?page=%s">下一页</a>' % (self.current_page+1) page_list.append(nex) return ''.join(page_list) 下面是一个套用实例 def index(request): all_count=models.Boy.objects.all().count()#计算一共 数据库中一共多少条数据 user_info=PageInfo(request.GET.get('page'),all_count,2) user_list=models.Boy.objects.all()[user_info.start():user_info.stop()] return render(request,'index.html',{'user_list':user_list,'page_info':user_info})
前端显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in user_list %} <li>{{ row.username}}</li> {% endfor %} </ul> {{ page_info.pager|safe}} {# 把Python的对象传入模板,自动执行,|safe 显示#} </body> </html>
参考:http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465
http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465