分頁器基本操作
用戶訪問一個網頁或者查看某些數據,如果數據量過大肯定需要按頁查看,不可能一個頁面顯示N條數據內容這里就用到了分頁器
- 首先往數據庫里插入數據,這里咱們進行腳本批量插入
# #腳本批量插入數據 book_list = [] for i in range(200): #創建200條數據 book = Book(title='book_%s'%i,price=i*i) book_list.append(book) #批量插入語法 Book.objects.bulk_create(book_list)
這樣一條insert語句包含多條數據,一次性插入
- 分頁器的基本語法及使用
def index(request): #分頁器對使用 #book_list = Book.objects.all()
#這里建議使用該種方法獲取Book對象的列表,否則會出現 ‘UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list:’
的報警信息。
book_list = Book.objects.get_queryset().order_by('id')
paginator = Paginator(book_list,10) #多少數據分一頁 print('coumt:',paginator.count) #數據總數 print('num_pages:',paginator.num_pages) #總頁數 print('page_range:',paginator.page_range) #頁碼列表 #獲取某頁的方式 #方式一 page1=paginator.page(1) #獲取第一頁的page對象 #方式二 for i in page1: #遍歷第一頁的所有數據 print(i) #根據用戶選擇來進行頁面顯示,獲取用戶的頁數 try: #這里捕獲異常到目的就是為了用戶選擇頁碼以外到值不會報錯 current_page=int(request.GET.get('page',1)) #這里要記得傳一個默認值否則會報錯,因為views 沒有獲取到page這個參數 current_page=paginator.page(current_page) except EmptyPage as e: current_page =paginator.page(1) return render(request,'index.html',locals())
#輸出內容
coumt: 200 num_pages: 20 page_range: range(1, 21) Book object (1) Book object (2) Book object (3) Book object (4) Book object (5) Book object (6) Book object (7) Book object (8) Book object (9) Book object (10)
- 前端頁面的顯示,傳遞分頁過后的對象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分頁器</title> </head> <body> <ul> {#這里傳遞分頁過后到內容#} {% for book in current_page %} <li>{{ book.title }} : {{ book.price }}</li> {% endfor %} </ul> </body> </html>
- 效果圖
因為默認訪問顯示的為第一頁內容,如是果想訪問其他頁需要 給后端傳遞 page 參數
更換頁碼 URL
點擊按鈕分頁
這里就用到bootstrap了,首先引入cdn,加在bootstrap,bookstarp官網給出了分頁器的模版,咱們可以直接拿過來用
網址 https://v3.bootcss.com/components/#pagination
<nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav>
這里他是寫好的多少個li標簽也就是多少頁,咱們要根據后端的 paginator_num_pages 進行range 循環進行動態展示頁碼,並根據點擊頁碼進行更改 ?page 的值,並對點擊標簽加深,
這里判斷對是當前點擊頁面與后端獲取頁面是否相等,如果相等給予li 標簽 calss =active 屬性
{% for item in paginator.page_range%} {% if current_num == item %} <li class="active"><a href="?page={{ item }}">{{ item }}</a></li> {% else %} <li><a href="?page={{ item }}">{{ item }}</a></li> {% endif %}
顯示效果
下面咱們配置上一頁和下一頁功能
{% if current_page.has_previous %} <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一頁</span></a> </li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">上一頁</span></a></li> {% if current_page.has_next %} <li><a href="?page={{ current_page.next_page_number }}" aria-label="Next"><span aria-hidden="true">下一頁</span></a></li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">下一頁</span></a></li> {% endif %}
這里如果不對當前頁面進行判斷是否還有上一頁或者下一頁
current_page.has_previous
current_page.has_next
就會出現上一頁或者下一頁 不存在數據的序號,如果用戶點擊了下一頁或者上一頁,則給當前頁面發送參數,分別意思為當前頁面對上一頁和當前頁面對下一頁
href="?page={{ current_page.previous_page_number }}
href="?page={{ current_page.next_page_number }}
判斷如果當前頁面對上一頁,或者下一頁為最后一頁,將li 標簽設置 disabled 屬性,變為不可點擊
美化分頁器
美化分頁器
理想中對分頁器是這樣的,點擊之后兩邊顯示可點擊的頁碼
首先咱們要對咱們的頁數進行判斷,超過多少頁的時候可以進行左右兩邊划分,划分過后,要控制點擊頁碼的兩邊的頁碼為正常數值,
如果兩邊的頁碼數量小於這個值,要對整體循環頁碼賦予新的值。
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分頁器</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <ul> {#這里傳遞分頁過后到內容#} {% for book in current_page %} <li>{{ book.title }} : {{ book.price }}</li> {% endfor %} </ul> {#分頁器#} <nav aria-label="Page navigation"> <ul class="pagination"> {% if current_page.has_previous %} <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一頁</span></a> </li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">上一頁</span></a></li> {% endif %} #這里對 記住對page_range 進行循環,不要對原始對range 進行循環 {% for item in page_range %} {% if current_num == item %} <li class="active"><a href="?page={{ item }}">{{ item }}</a></li> {% else %} <li><a href="?page={{ item }}">{{ item }}</a></li> {% endif %} {% endfor %} {% if current_page.has_next %} <li><a href="?page={{ current_page.next_page_number }}" aria-label="Next"><span aria-hidden="true">下一頁</span></a></li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">下一頁</span></a></li> {% endif %} </ul> </nav> </body> </html>
views
from django.shortcuts import render from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # Create your views here. def index(request): #分頁器對使用 # book_list = Book.objects.all() book_list = Book.objects.get_queryset().order_by('id') paginator = Paginator(book_list,10) #多少數據分一頁 current_num = int(request.GET.get('page', 1)) paginator_num_pages =paginator.num_pages print(paginator_num_pages) #進行判斷超過多少值進行左右循環,11這里是左5右5 if paginator.num_pages>11:
#進行判斷如果頁碼數上一頁-5的時候小於1,就對循環頁面重新賦值,上一頁同理 if current_num -5<1: page_range=range(1,14) elif current_num +5>paginator_num_pages: page_range=range(paginator_num_pages-11,paginator_num_pages+1) else: page_range=range(current_num-5,current_num+6) else: page_range=paginator.page_range #根據用戶選擇來進行頁面顯示,獲取用戶的頁數 try: #這里捕獲異常到目的就是為了用戶選擇頁碼以外到值不會報錯 #這里要記得傳一個默認值否則會報錯,因為views 沒有獲取到page這個參數 current_page=paginator.page(current_num) except EmptyPage as e: current_page =paginator.page(1) return render(request,'index.html',locals())