分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该显示在页面上的数据在数据库表中的起始位置。

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)
   # 可以单页的数据,就可以从前端传数据动态取第几页了!
#-----------------------------------------------------------------
View Code
视图
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())
View Code

   前端

<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>
View Code

[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})
View Code

 前端显示

<!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>
View Code

 

 

 

 

参考:http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465

 

 

http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465

posted on 2017-06-26 22:04  Martin8866  阅读(473)  评论(0编辑  收藏  举报