3期 58-1 分页
当需要展示的数据量多的时候,就要把一个大长页面分成很多小的页面,并给每个小页面底部添加页面按钮方便切换。
要成功分页,需要告诉服务器4个信息:
- 数据的总个数是多少
- 每页展示多少个数据
- 当前页的页码
- 每个页面底部需要多少个页码按钮
一、Django内置的分页
Django的内置分页功能非常简单,大致只能做出如下效果:

from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # L为简单的示例数据,真实情况下应从数据库获取 L = [] for i in range(1, 550): L.append(i) def index1(request): """ Django内置的分页功能 """ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger current_page = request.GET.get('p') paginator = Paginator(L, 10) # 实例化出paginator对象。第一参数为数据,第二参数为每页的数据条数 # paginator.per_page: 每页显示条目数量 # paginator.count: 数据总个数 # paginator.num_pages: 总页数 # paginator.page_range: 总页数的索引范围,如: (1,10),(1,200) # paginator.page: page对象 try: current_page_obj = paginator.page(current_page) # current_page_obj.has_next 是否有下一页 # current_page_obj.next_page_number 下一页页码 # current_page_obj.has_previous 是否有上一页 # current_page_obj.previous_page_number 上一页页码 # current_page_obj.object_list 分页之后的数据列表 # current_page_obj.number 当前页 # current_page_obj.paginator paginator对象 except PageNotAnInteger: current_page_obj = paginator.page(1) # 第一页 except EmptyPage: current_page_obj = paginator.page(paginator.num_pages) # 最后一页 return render(request, 'index1.html', {'current_page_obj': current_page_obj})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for item in current_page_obj %} <li>{{ item }}</li> {% endfor %} </ul> {% if current_page_obj.has_previous %} <a href="index1.html?p={{ current_page_obj.previous_page_number }}">上一页</a> {% else %} <a href="index1.html?p={{ current_page_obj.number }}">上一页</a> {% endif %} {% if current_page_obj.has_next %} <a href="index1.html?p={{ current_page_obj.next_page_number }}">下一页</a> {% else %} <a href="index1.html?p={{ current_page_obj.number }}">下一页</a> {% endif %} <span>{{ current_page_obj.number }}/{{ current_page_obj.paginator.num_pages }}</span> </body> </html>
二、对Django内置分页扩展,实现更强的功能
自己写个类,自定义个可以返回页码范围的方法,可实现如下效果:

from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # L为简单的示例数据,真实情况下应从数据库获取 L = [] for i in range(1, 550): L.append(i) class iPaginator(Paginator): def __init__(self, current_page_number, count_per_page, *args, **kwargs): self.current_page_number = int(current_page_number) self.count_per_page = int(count_per_page) super(iPaginator, self).__init__(*args, **kwargs) def pages_rg(self): if self.num_pages <= self.count_per_page: pages_rg = [i for i in range(1, self.num_pages + 1)] else: part = int(self.count_per_page/2) if self.current_page_number <= part: pages_rg = [i for i in range(1, self.count_per_page + 1)] elif self.current_page_number > self.num_pages-part: pages_rg = [i for i in range(self.num_pages-self.count_per_page+1, self.num_pages+1)] else: pages_rg = [i for i in range(self.current_page_number-part, self.current_page_number+part+1)] return pages_rg def index3(request): current_page_number = int(request.GET.get('p')) count_per_page = 11 mp = iPaginator(current_page_number, 11, L, 10) try: current_page_obj = mp.page(current_page_number) pages_rg = mp.pages_rg() except PageNotAnInteger: current_page_obj = mp.page(1) except EmptyPage: current_page_obj = mp.page(mp.num_pages) return render(request, 'index3.html', {'current_page_obj': current_page_obj, "pages_rg": pages_rg})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for item in current_page_obj %} <li>{{ item }}</li> {% endfor %} </ul> {#上一页#} {% if current_page_obj.has_previous %} <a href="index3.html?p={{ current_page_obj.previous_page_number }}">上一页</a> {% else %} <a href="index3.html?p={{ current_page_obj.number }}">上一页</a> {% endif %} {#页码#} {% for i in pages_rg %} {% if i == current_page_obj.number %} <a href="index3.html?p={{ i }}" style="background-color: navy; color: white">{{ i }}</a> {% else %} <a href="index3.html?p={{ i }}">{{ i }}</a> {% endif %} {% endfor %} {#下一页#} {% if current_page_obj.has_next %} <a href="index3.html?p={{ current_page_obj.next_page_number }}">下一页</a> {% else %} <a href="index3.html?p={{ current_page_obj.number }}">下一页</a> {% endif %} {#计数#} <span>{{ current_page_obj.number }}/{{ current_page_obj.paginator.num_pages }}</span> </body> </html>
三、完全自定义的分页
完全自己写,不依赖任何内置的分页功能,且结合进bootstrap实现更好的效果:

class MyPaginator(object): def __init__(self, items_count, current_page_num, per_page_items_count=10, page_labels_count=11): """ :param items_count: 数据总个数 :param current_page_num: 当前页的页码 :param per_page_items_count: 每页显示的数据个数 :param page_labels_count: 每页的页码标签数量 """ self.items_count = items_count try: v = int(current_page_num) if v <= 0: v = 1 self.current_page_num = v except Exception as e: self.current_page_num = 1 self.per_page_items_count = per_page_items_count self.page_labels_count = page_labels_count @property def pages_count(self): """ :return: 总页数 """ a, b = divmod(self.items_count, self.per_page_items_count) if b == 0: return a return a+1 def items_show_start_num(self): """ :return: 当前页数据的起始索引号 """ return (self.current_page_num-1) * self.per_page_items_count def items_show_end_num(self): """ :return: 当前页数据的结束索引号 """ return self.current_page_num * self.per_page_items_count def previous_page_num(self): """ :return: 当前页的前一页 """ if self.current_page_num <= 1: return 1 else: return self.current_page_num - 1 def next_page_num(self): """ :return: 当前页的后一页 """ if self.current_page_num >= self.pages_count: return self.pages_count else: return self.current_page_num + 1 def page_num_range(self): """ :return: 根据当前页的页码数,确定要返回的页码范围 """ if self.pages_count <= self.page_labels_count: page_num_range = [i for i in range(1, self.pages_count + 1)] else: part = int(self.page_labels_count/2) if self.current_page_num <= part: page_num_range = [i for i in range(1, self.page_labels_count + 1)] elif self.current_page_num > self.pages_count - part: page_num_range = [i for i in range(self.pages_count-self.page_labels_count+1, self.pages_count+1)] else: page_num_range = [i for i in range(self.current_page_num-part, self.current_page_num+part+1)] return page_num_range def origin_pager(self, my_url): page_num_tag_list = [] pre_page_num_tag = '<a href="{my_url}?p={page_num}">下一页</a>'.format(my_url=my_url, page_num=self.previous_page_num()) page_num_tag_list.append(pre_page_num_tag) for i in self.page_num_range(): if i == self.current_page_num: page_num_tag = '<a style="color:red" href="{my_url}?p={page_num}">{page_num}</a>'.format(my_url=my_url, page_num=i) else: page_num_tag = '<a href="{my_url}?p={page_num}">{page_num}</a>'.format(my_url=my_url, page_num=i) page_num_tag_list.append(page_num_tag) next_page_num_tag = '<a href="{my_url}?p={page_num}">下一页</a>'.format(my_url=my_url, page_num=self.next_page_num()) page_num_tag_list.append(next_page_num_tag) return ''.join(page_num_tag_list) def pager(self, my_url): """ 结合bootstrap的css,生成漂亮的分页模块 :param my_url: 要放置分页模块页码的url :return: 已经写好的html字符串,可以通过模板语言直接成html代码(注意加safe标识安全,否则不能渲染) """ page_num_tag_list = [] pre_page_num_tag = '<li><a aria-label="Previous" href="{my_url}?p={page_num}"><span aria-hidden="true">«</span></a></li>'.format(my_url=my_url, page_num=self.previous_page_num()) page_num_tag_list.append(pre_page_num_tag) for i in self.page_num_range(): if i == self.current_page_num: page_num_tag = '<li class="active"><a href="{my_url}?p={page_num}">{page_num}</a></li>'.format(my_url=my_url, page_num=i) else: page_num_tag = '<li><a href="{my_url}?p={page_num}">{page_num}</a></li>'.format(my_url=my_url, page_num=i) page_num_tag_list.append(page_num_tag) next_page_num_tag = '<li><a aria-label="Next" href="{my_url}?p={page_num}"><span aria-hidden="true">»</span></a></li>'.format(my_url=my_url, page_num=self.next_page_num()) page_num_tag_list.append(next_page_num_tag) return ''.join(page_num_tag_list)
from django.shortcuts import render def index5(request): """ 结合进bootstrap的自定义分页 :param request: :return: """ current_page_num = request.GET.get("p") from app01.pager import MyPaginator myPaginitor_obj = MyPaginator(550, current_page_num, page_labels_count=7) items_list = L[myPaginitor_obj.items_show_start_num():myPaginitor_obj.items_show_end_num()] p = myPaginitor_obj.pager("index5.html") return render(request, 'index5.html', { "myPaginitor_obj": myPaginitor_obj, "items_list": items_list, "p": p})
<!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 i in items_list %} <li>{{ i }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {{ p|safe }} </ul> </nav> </body> </html>
浙公网安备 33010602011771号