一、函数版 (未更新)
1 def show_books(request): 2 """ 3 自定制分页器(函数版): 4 :param request: 5 :return: data_list: 希望展示在当前页面的数据集合 6 page_html: 页码导航条html 7 """ 8 url = request.path_info 9 10 all_book_list = models.Book.objects.all() 11 total_data = all_book_list 12 13 try: 14 total_data_num = total_data.count() # 总数据条数 15 except TypeError: 16 total_data_num = len(total_data) 17 18 current_page_id = request.GET.get('page') # 当前页码id 19 try: 20 current_page_id = int(current_page_id) 21 except (ValueError, TypeError): 22 current_page_id = 1 23 24 perpage_data_num = 10 # 每个页面展示数据条数 25 26 quotient, more = divmod(total_data_num, perpage_data_num) 27 total_page_num = quotient+1 if more != 0 or quotient == 0 and more == 0 else quotient # 总页码数 28 29 # 控制当前页码乱入负数、太大数等情况 30 if current_page_id < 1: 31 current_page_id = 1 32 elif current_page_id > total_page_num: 33 current_page_id = total_page_num 34 35 pagedata_start_id = (current_page_id - 1) * perpage_data_num 36 pagedata_end_id = current_page_id * perpage_data_num 37 38 nvgtnbar_page_num = 9 # 页面中页码导航条显示的页码个数 39 left_page_id = current_page_id - nvgtnbar_page_num // 2 # 页码导航条最左边的页码id 40 right_page_id = current_page_id + nvgtnbar_page_num // 2 # 页码导航条最右边的页码id 41 42 # 两端控制溢出 43 if left_page_id < 1: 44 left_page_id = 1 45 right_page_id = nvgtnbar_page_num 46 if right_page_id > total_page_num: 47 right_page_id = total_page_num 48 left_page_id = total_page_num - nvgtnbar_page_num + 1 49 50 # 数据量不足的情况下,控制页码导航条的显示 51 if total_page_num < nvgtnbar_page_num: 52 left_page_id = 1 53 right_page_id = total_page_num 54 55 page_html = '' 56 prev_page_id = current_page_id - 1 if current_page_id != 1 else current_page_id 57 next_page_id = current_page_id + 1 if current_page_id != total_page_num else current_page_id 58 first_page_html = '<li><a href="{}?page=1">首页</a></li>'.format(url) 59 last_page_html = '<li><a href="{}?page={}">尾页</a></li>'.format(url, total_page_num) 60 prev_page_html = '<li><a href="{}?page={}">上一页</a></li>'.format(url, prev_page_id) 61 next_page_html = '<li><a href="{}?page={}">下一页</a></li>'.format(url, next_page_id) 62 63 for i in range(left_page_id, right_page_id + 1): 64 if i == current_page_id: 65 page_html += '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(url, i) 66 else: 67 page_html += '<li><a href="{0}?page={1}">{1}</a></li>'.format(url, i) 68 69 page_html = prev_page_html + first_page_html + page_html + last_page_html + next_page_html 70 71 data_list = total_data[pagedata_start_id:pagedata_end_id] 72 73 return render(request, 'book_list.html', {'data_list': data_list, 'page_html': page_html})
二、分页器(封装版) (已更新)
class Pagination(object): def __init__(self, request, data_set, perpage_data_count=10, nvgbar_page_count=9): """ 自定制分页器: 供调用属性 设定接收分页器处理后结果的对象为mypage mypage.data: 希望展示在当前页面上的数据集合 mypage.page_html:页码导航栏html :param request: request请求 :param data_set: 希望进行分页处理的容器性数据对象,即总数据 :param perpage_data_count: 希望每个页面要展示的数据条数,默认10条 :param nvgbar_page_count: 希望页码导航条展示的页码数,默认9个页码 """ self.url = request.path_info self.perpage_data_count = perpage_data_count self.nvgbar_page_count = nvgbar_page_count current_page_id = request.GET.get('page') try: current_page_id = int(current_page_id) except (ValueError, TypeError): current_page_id = 1 self.current_page_id = current_page_id try: total_data_count = data_set.count() except TypeError: total_data_count = len(data_set) # quotient, more = divmod(total_data, self.perpage_data) # self.total_page_count = quotient + 1 if more != 0 or quotient == 0 and more == 0 else quotient # 总页码数 self.total_page_count, more = divmod(total_data_count, self.perpage_data_count) if more: self.total_page_count += 1 # 控制当前页码乱入负数、太大数等情况(两个if,顺序不能反) if self.current_page_id > self.total_page_count: self.current_page_id = self.total_page_count if self.current_page_id < 1: self.current_page_id = 1 perpagedata_start = (self.current_page_id - 1) * self.perpage_data_count perpagedata_end = self.current_page_id * self.perpage_data_count self.data = data_set[perpagedata_start: perpagedata_end] @property def page_html(self): left_page_id = self.current_page_id - self.nvgbar_page_count // 2 # 页码导航条最左边的页码id right_page_id = self.current_page_id + self.nvgbar_page_count // 2 # 页码导航条最右边的页码id # 两端控制溢出 if left_page_id < 1: left_page_id = 1 right_page_id = self.nvgbar_page_count if right_page_id > self.total_page_count: right_page_id = self.total_page_count left_page_id = self.total_page_count - self.nvgbar_page_count + 1 # 数据量不足的情况下,控制页码导航条的显示 if self.total_page_count < self.nvgbar_page_count: left_page_id = 1 right_page_id = self.total_page_count page_html_list = ['<nav aria-label="Page navigation"><ul class="pagination">', ] prev_page_id = self.current_page_id - 1 if self.current_page_id != 1 else self.current_page_id next_page_id = self.current_page_id + 1 if self.current_page_id != self.total_page_count else self.current_page_id page_html_list.append('<li><a href="{}?page={}">«</a></li>'.format(self.url, prev_page_id)) page_html_list.append('<li><a href="{}?page=1">首页</a></li>'.format(self.url)) for i in range(left_page_id, right_page_id + 1): if i == self.current_page_id: page_html_list.append('<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url, i)) else: page_html_list.append('<li><a href="{0}?page={1}">{1}</a></li>'.format(self.url, i)) page_html_list.append('<li><a href="{}?page={}">尾页</a></li>'.format(self.url, self.total_page_count)) page_html_list.append('<li><a href="{}?page={}">»</a></li>'.format(self.url, next_page_id)) page_html_list.append('</ul></nav>') page_html = ''.join(page_html_list) return page_html
视图中使用分页器:
模板html中调用
from utils.mypage import Pagination def show_books(request): book_list = models.Books.objects.all() # book_list = models.Books.objects.all().value_list('title', 'authors') show_obj = Pagination(request, book_list) return render(request, 'books.html', {'show_obj': show_obj})
模板中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/bootstrap/bootstrap3.3.7-min.css"> </head> <body> <div class="container"> <table class="table table-bordered"> <thead> <tr> <td>序号</td> <td>ID</td> <td>书名</td> </tr> </thead> <tbody> {% for book in show_obj.data %} <tr> <td>{{ forloop.counter }}</td> <td>{{ book.id }}</td> <td>{{ book.title }}</td> </tr> {% endfor %} </tbody> </table> {{ show_obj.page_html|safe }} </div> </body> </html>
ok