應用說明:
瀏覽文章會有很多的頁碼,就需要分頁來實現,因為不可能把所有的頁碼放在文章列表的下面
一:實例准備:
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后面是 整數 超過總頁,顯示最后一頁
每頁 十個頁碼