Django之分頁
阿新 • • 發佈:2020-07-27
1. Django的內建分頁
1.1 views.py
from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger L = [] for i in range(999): L.append(i) def index(request): current_page = request.GET.get('p') paginator = Paginator(L, 10) # per_page: 每頁顯示條目數量# count: 資料總個數 # num_pages:總頁數 # page_range:總頁數的索引範圍,如: (1,10),(1,200) # page: page物件 try: posts = paginator.page(current_page) # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼# object_list 分頁之後的資料列表 # number 當前頁 # paginator paginator物件 except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request, 'index.html', {'posts': posts})
1.2 index.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <ul> {% for item in posts %} <li>{{ item }}</li> {% endfor %} </ul> <div class="pagination"> <span class="step-links"> {% if posts.has_previous %} <a href="?p={{ posts.previous_page_number }}">Previous</a> {% endif %} <span class="current"> Page {{ posts.number }} of {{ posts.paginator.num_pages }}. </span> {% if posts.has_next %} <a href="?p={{ posts.next_page_number }}">Next</a> {% endif %} </span> </div> </body> </html>
2. 擴充套件Django內建分頁
2.1 views.py
from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger class CustomPaginator(Paginator): def __init__(self, current_page, max_pager_num, *args, **kwargs): self.current_page = int(current_page) self.max_pager_num = max_pager_num super(CustomPaginator, self).__init__(*args, **kwargs) def page_num_range(self): # 當前頁面 # self.current_page # 總頁數 # self.num_pages # 最多顯示的頁碼個數 # self.max_pager_num print(1) if self.num_pages < self.max_pager_num: return range(1, self.num_pages + 1) print(2) part = int(self.max_pager_num / 2) if self.current_page - part < 1: return range(1, self.max_pager_num + 1) print(3) if self.current_page + part > self.num_pages: return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1) print(4) return range(self.current_page - part, self.current_page + part + 1) L = [] for i in range(999): L.append(i) def index(request): current_page = request.GET.get('p') paginator = CustomPaginator(current_page, 11, L, 10) # per_page: 每頁顯示條目數量 # count: 資料總個數 # num_pages:總頁數 # page_range:總頁數的索引範圍,如: (1,10),(1,200) # page: page物件 try: posts = paginator.page(current_page) # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼 # object_list 分頁之後的資料列表 # number 當前頁 # paginator paginator物件 except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request, 'index.html', {'posts': posts})
2.2 index.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <ul> {% for item in posts %} <li>{{ item }}</li> {% endfor %} </ul> <div class="pagination"> <span class="step-links"> {% if posts.has_previous %} <a href="?p={{ posts.previous_page_number }}">Previous</a> {% endif %} {% for i in posts.paginator.page_num_range %} <a href="?p={{ i }}">{{ i }}</a> {% endfor %} {% if posts.has_next %} <a href="?p={{ posts.next_page_number }}">Next</a> {% endif %} </span> </div> </body> </html>
3. 自定義分頁
3.1 自定義分頁外掛
pager.py
class Paginator(object): def __init__(self, totalCount, currentPage, perPageItemNum=10, maxPageNum=11): """ totalCount:資料總個數 currentPage:當前頁 perPageItemNum: 每頁顯示的行數 maxPageNum:最多顯示的頁碼個數 """ self.total_count = totalCount try: v = int(currentPage) if v <= 0: v = 1 self.current_page = v except Exception as e: self.current_page = 1 self.per_page_item_num = perPageItemNum self.max_page_num = maxPageNum @property def start(self): """資料切片的起始位置""" return (self.current_page-1) * self.per_page_item_num @property def end(self): """資料切片的結束位置""" return self.current_page * self.per_page_item_num @property def num_pages(self): """總的頁數""" a, b = divmod(self.total_count, self.per_page_item_num) if b == 0: return a return a + 1 def page_num_range(self): """頁碼範圍""" part = int(self.max_page_num / 2) # 總的頁數少於預設要顯示的頁碼數 if self.num_pages < self.max_page_num: return range(1, self.num_pages + 1) # 當前頁碼處於第一頁的前一半位置 if self.current_page - part < 1: return range(1, self.max_page_num + 1) # 當前頁碼處於最後一頁的後一半位置 if self.current_page + part > self.num_pages: return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1) return range(self.current_page - part, self.current_page + part + 1) def page_str(self): """生成所有的頁碼""" # 建立一個儲存所有頁碼的容器 page_list = [] # 生成首頁和上一頁的頁碼 first = "<li><a href='?p=1'>首頁</a></li>" page_list.append(first) if self.current_page == 1: the_prev = "<li><a href='#'>上一頁</a></li>" else: the_prev = "<li><a href='?p=%s'>上一頁</a></li>" % (self.current_page - 1, ) page_list.append(the_prev) # 生成中間所有頁的頁碼 for i in self.page_num_range(): if i == self.current_page: temp = "<li class='active'><a href='?p=%s'>%s</a></li>" % (i, i, ) else: temp = "<li><a href='?p=%s'>%s</a></li>" % (i, i, ) page_list.append(temp) # 生成下一頁和尾頁的頁碼 if self.current_page == self.num_pages: the_next = "<li><a href='#'>下一頁</a></li>" else: the_next = "<li><a href='?p=%s'>下一頁</a></li>" % (self.current_page + 1, ) page_list.append(the_next) last = "<li><a href='?p=%s'>尾頁</a></li>" % (self.num_pages, ) page_list.append(last) # 列表容器中的各個頁碼轉換為字串 result = ''.join(page_list) return result
3.2 在後臺函數中呼叫自定義分頁外掛
views.py
user_list = [] for i in range(1, 999): temp = {'username': 'root' + str(i), 'age': i, } user_list.append(temp) def index(request): # 獲取當前頁碼號 current_page = int(request.GET.get('p')) # 匯入自定義分頁外掛 from app01.pager import Paginator # 引數依次為: 資料總個數, 當前頁碼號, 每頁顯示的行數, 最多顯示的頁碼個數 # 後兩個引數預設為: 10, 11 obj = Paginator(999, current_page,) # obj物件中可呼叫的屬性(方法): # start 當前頁的起始條目索引 # end 當前頁的結束條目索引 # page_str() 生成的所有頁碼結構和樣式 data_list = user_list[obj.start:obj.end] return render(request, 'index.html', {'data': data_list, 'page_obj': obj, })
3.3 模板檔案index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> {# 資料內容 #} <ul> {% for row in data %} <li>{{ row.username }} -- {{ row.age }}</li> {% endfor %} </ul> {# 分頁的內容 #} <ul class="pagination"> {{ page_obj.page_str|safe }} </ul> </body> </html>