分页器的使用

应用说明:

  浏览文章会有很多的页码,就需要分页来实现,因为不可能把所有的页码放在文章列表的下面

 

一:实例准备:

  1. models表结构为:

1 class Book(models.Model):
2     title=models.CharField(max_length=32)
3     price=models.DecimalField(max_digits=6,decimal_places=1)

 

  2. 通过更高效的方式向数据库添加白条数据方法:

 1 #批量导入数据,利用bulk_create效率会更高效
 2 第一种:效率低
 3 for i in range(100):
 4     Book.objects.create(title="book"+str(i),price=i*4)
 5 
 6 第二种:效率高
 7 bookList=[]
 8 for i in range(100):
 9     book=Book(title="book"+str(i),price=i*4)
10     bookList.append(book)
11 
12 Book.objects.bulk_create(bookList)

 

  3. 分页的使用方法(views视图函数):

 1 # 导入的模块
 2 from .models import *
 3 from django.core.paginator import Paginator,EmptyPage, PageNotAnInteger
 4 
 5 # 分页器的用法
 6 book_list = Book.objects.all()  # 所有书籍对象
 7 paginator = Paginator(book_list, 2)  # 每页显示2个,所有方法都在paginator分页程序
 8 
 9 # 分页器的三个属性
10 print("count:", paginator.count)  # 数据总数
11 print("num_pages", paginator.num_pages)  # 总页数 book_list/2
12 print("page_range", paginator.page_range)  # 页码的列表() book_list 100 ,显示2个,这里就是(1,51)
13 
14 # 获取前端传来的页码 get请求
15 pagenum = request.GET.get('page', 1)  # 默认第一页,这里只是得到页码(注意是字符串)
16 
17 # 获取第一页的对象
18 pagenum = int(pagenum)
19 page1 = paginator.page(pagenum)
20 
21 # 如何获取当前页的数据对象,数据
22 for i in page1:  # 遍历第1页的所有数据对象
23     print(i)
24 
25 print(page1.object_list)  # 第1页的所有数据,遍历
26 
27 #
28 page2 = paginator.page(2) # 第二页的所有数据,遍历
29 
30 # 上一页,下一页
31 print(page2.has_next())  # 是否有下一页
32 print(page2.next_page_number())  # 下一页的页码
33 print(page2.has_previous())  # 是否有上一页
34 print(page2.previous_page_number())  # 上一页的页码
35 
36 # 抛错,注意报错的位置
37 # page=paginator.page(12)   # error:EmptyPage 超出范围显示空
38 
39 # page=paginator.page("z")   # error:PageNotAnInteger 传入值错误

 

  4. 前端页面渲染判断上一页或者下一页方法:

 1 <ul class="pagination">
 2 
 3     {% if book_list.has_previous %}
 4      <li><a href="/index/?page={{ book_list.previous_page_number }}" aria-label="Previous">上一页</a></li>
 5     {% else %}
 6         <li class="disabled"><a href="" aria-label="Previous">上一页</a></li>
 7     {% endif %}
 8 
 9      中间页码(1,2,3)内容
10 
11      {% if book_list.has_next %}
12         <li><a href="/index/?page={{ book_list.next_page_number }}" aria-label="Next">下一页</a></li>
13     {% else %}
14         <li class="disabled"><a href="" aria-label="Next">下一页</a></li>
15     {% endif %}
16 
17 </ul>

 

二:完整实际例子,注意前端循环的页码对象

创建Django项目,创建app01项目

  1. urls代码:

1 from app01 import views
2 
3 urlpatterns = [
4     url(r'^admin/', admin.site.urls),
5     url(r'^index/', views.index),
6 ]

 

  2. views视图函数代码:

 1 def index(request):
 2     book_list = Book.objects.all()  # 全部对象
 3 
 4     paginator = Paginator(book_list, 2)  # 单页显示多少个
 5 
 6     # currentPage = None
 7     # pageRange = None
 8 
 9     # try:  # 异常处理,有可能用户通过url https://127.0.0.1:?page= 访问,需要对page=做处理
10     #     global currentPage, pageRange
11     page = request.GET.get('page', 1)  # 获取页码,默认1
12     print(type(page))  # 打印类型 int 类型
13     print(page)
14 
15     # 处理访问路径的合法性,(解决抛错异常error:PageNotAnInteger 传入值错误)
16     if page == '0' or page == 1:
17         currentPage = 1 # 前端传来的是0,默认给第一页
18     elif page.isdigit():
19         currentPage = int(page) # 前端传来数据页码,前端传过来字符串,需要转换
20     else:
21         currentPage = 1 # 前端传来的不是整数,默认给第一页
22 
23     # 如果页码过多,使用,最后得到pageRange就是要显示的页码个数()
24     if paginator.num_pages > 10: # 总页码大于10,就不能让分页都显示出来了
25 
26         if currentPage - 5 < 1: # 前端传来是小于6的页码,选中在左边 (第一页)
27             pageRange = range(1, 11)
28         elif currentPage > paginator.num_pages: # 前端传来的比总页还大,我应该给最后一页,并且要选中 (解决抛错异常error:EmptyPage 超出范围显示空)
29             pageRange = range(paginator.num_pages, paginator.num_pages + 1) # 最后一页,只有一个数
30             currentPage = paginator.num_pages
31         elif currentPage + 5 > paginator.num_pages: # 前端传来的加5大于总页,选中在右边 (最后一页)
32             pageRange = range(currentPage - 5, paginator.num_pages + 1)
33         else:
34             pageRange = range(currentPage - 5, currentPage + 5) # 传来的 中间页
35 
36     else:
37         pageRange = paginator.page_range  # 这个时候就不需要分页
38     print(pageRange)
39 
40     try:
41         # 如果页码不大于10,也会有用户输入会超过的时候,这里就需要try 的抛错了
42         book_list = paginator.page(currentPage)  # 获取第page页的对象,是这里抛错,就是判断前端返回,或者url直接访问的合法性
43 
44         # except PageNotAnInteger:  # 这里应该不需要异常的,上面在路径的合法性解决了
45         #     book_list = paginator.page(1)  # 传入的是错误的值,比如page是字母,特殊符号等,那就显示第一页的对象
46         #     pageRange = range(1, 11) # 显示第一页内容,分页个数 1-10就可以
47     except EmptyPage:
48         book_list = paginator.page(paginator.num_pages)  # 超出就显示最后一页的对象
49         currentPage = paginator.num_pages # 超出总页,需要重新给页码赋值一个最后页码
50 
51     return render(request, "index.html", {'book_list': book_list, 'paginator': paginator, 'currentPage': currentPage, 'pageRange': pageRange})

 

  3. index.html代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <!-- 新 Bootstrap 核心 CSS 文件 -->
 7     <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
 8 </head>
 9 <body>
10 
11 
12 <ul>
13    {% for book in book_list %}
14        <li>{{ book.title }}----------->{{ book.price }}</li>
15    {% endfor %}
16 
17 </ul>
18 
19     {#重点加这个pagination#}
20     <ul class="pagination">  
21     
22         {% if book_list.has_previous %}
23     {#        重点Previous#}
24          <li><a href="/index/?page={{ book_list.previous_page_number }}" aria-label="Previous">上一页</a></li>  
25         {% else %}
26             <li class="disabled"><a href="" aria-label="Previous">上一页</a></li>
27         {% endif %}
28     
29         {% for pageNum in pageRange %} 
30     {#        没有超出总页并且是选中的#}
31            {% if currentPage == pageNum %}
32               <li class="active"><a href="/index/?page={{ pageNum }}">{{ pageNum }}</a></li>
33     {#        超出总页码#}
34            {% elif currentPage > paginator.num_pages%}
35                <li class="active"><a href="/index/?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
36            {% else %}
37     {#        没有超出总页#}
38                <li><a href="/index/?page={{ pageNum }}">{{ pageNum }}</a></li>
39            {% endif %}
40         {% endfor %}
41     
42     
43         {% if book_list.has_next %}
44     {#        重点Next#}
45             <li><a href="/index/?page={{ book_list.next_page_number }}" aria-label="Next">下一页</a></li>  
46         {% else %}
47             <li class="disabled"><a href="" aria-label="Next">下一页</a></li>
48         {% endif %}
49     </ul>
50 
51 
52 
53 </body>
54 </html>

 

最后结果:

  url http://127.0.0.1:8000/?page=

  page后面是 字母,负数,0,其他字符   显示第一页分页

  page后面是 整数 显示相应的分页

  page后面是 整数 超过总页,显示最后一页

  每页 十个页码

posted @ 2017-12-23 17:30  liqianlong  阅读(1508)  评论(0编辑  收藏  举报