Django_分页
目录
简介
Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py
.它可以接收列表、元组或其它可迭代的对象。
class Paginator: def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True): self.object_list = object_list self._check_object_list_is_ordered() self.per_page = int(per_page) self.orphans = int(orphans) self.allow_empty_first_page = allow_empty_first_page def validate_number(self, number): """Validate the given 1-based page number.""" try: number = int(number) except (TypeError, ValueError): raise PageNotAnInteger(_('That page number is not an integer')) if number < 1: raise EmptyPage(_('That page number is less than 1')) if number > self.num_pages: if number == 1 and self.allow_empty_first_page: pass else: raise EmptyPage(_('That page contains no results')) return number def get_page(self, number): """ Return a valid page, even if the page argument isn't a number or isn't in range. """ try: number = self.validate_number(number) except PageNotAnInteger: number = 1 except EmptyPage: number = self.num_pages return self.page(number) def page(self, number): """Return a Page object for the given 1-based page number.""" number = self.validate_number(number) bottom = (number - 1) * self.per_page top = bottom + self.per_page if top + self.orphans >= self.count: top = self.count return self._get_page(self.object_list[bottom:top], number, self) def _get_page(self, *args, **kwargs): """ Return an instance of a single page. This hook can be used by subclasses to use an alternative to the standard :cls:`Page` object. """ return Page(*args, **kwargs) @cached_property def count(self): """Return the total number of objects, across all pages.""" try: return self.object_list.count() except (AttributeError, TypeError): # AttributeError if object_list has no count() method. # TypeError if object_list.count() requires arguments # (i.e. is of type list). return len(self.object_list) @cached_property def num_pages(self): """Return the total number of pages.""" if self.count == 0 and not self.allow_empty_first_page: return 0 hits = max(1, self.count - self.orphans) return int(ceil(hits / float(self.per_page))) @property def page_range(self): """ Return a 1-based range of pages for iterating through within a template for loop. """ return range(1, self.num_pages + 1) def _check_object_list_is_ordered(self): """ Warn if self.object_list is unordered (typically a QuerySet). """ ordered = getattr(self.object_list, 'ordered', None) if ordered is not None and not ordered: obj_list_repr = ( '{} {}'.format(self.object_list.model, self.object_list.__class__.__name__) if hasattr(self.object_list, 'model') else '{!r}'.format(self.object_list) ) warnings.warn( 'Pagination may yield inconsistent results with an unordered ' 'object_list: {}.'.format(obj_list_repr), UnorderedObjectListWarning, stacklevel=3 )
基本语法
# -*- coding:utf-8 -*- from django.core.paginator import Paginator objects = ['john', 'paul', 'george', 'ringo', 'lucy', 'meiry', 'checy', 'wind', 'flow', 'rain'] p = Paginator(objects, 3) # 3条数据为一页,实例化分页对象 print(p.count) # 10 对象总共10个元素 print(p.num_pages) # 4 对象可分4页 print(p.page_range) # range(1, 5) 对象页的可迭代范围 page1 = p.page(1) # 取对象的第一分页对象 print(page1.object_list) # 第一分页对象的元素列表['john', 'paul', 'george'] print(page1.number) # 第一分页对象的当前页值 1 page2 = p.page(2) # 取对象的第二分页对象 print(page2.object_list) # 第二分页对象的元素列表 ['ringo', 'lucy', 'meiry'] print(page2.number) # 第二分页对象的当前页码值 2 print(page1.has_previous()) # 第一分页对象是否有前一页 False print(page1.has_other_pages()) # 第一分页对象是否有其它页 True print(page2.has_previous()) # 第二分页对象是否有前一页 True print(page2.has_next()) # 第二分页对象是否有下一页 True print(page2.next_page_number()) # 第二分页对象下一页码的值 3 print(page2.previous_page_number()) # 第二分页对象的上一页码值 1 print(page2.start_index()) # 第二分页对象的元素开始索引 4 print(page2.end_index()) # 第2分页对象的元素结束索引 6
示例
示例1 使用django内置Paginator模块
from django.urls import path,re_path,include from testpaginator import views urlpatterns = [ re_path("index/",views.Index.as_view()), ]
from django.db import models class Product(models.Model): name = models.CharField(max_length=64) price = models.IntegerField() def __str__(self): return "{}-{}".format(self.name,self.price)
from django.shortcuts import render from django.views import View from . import models from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage class Index(View): def get(self,request): product_obj_list = models.Product.objects.all() paginator = Paginator(product_obj_list,10) page = request.GET.get("page") try: product_obj_list_new = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. product_obj_list_new = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. product_obj_list_new = paginator.page(paginator.num_pages) context = { "product_obj_list":product_obj_list_new } return render(request,"page.html",context)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ol> {% for product_obj in product_obj_list %} {# Each "contact" is a Contact model object. #} <li>{{ product_obj }}</li> {% endfor %} </ol> <div class="pagination"> <span class="step-links"> {% if product_obj_list.has_previous %} <a href="?page={{ product_obj_list.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ product_obj_list.number }} of {{ product_obj_list.paginator.num_pages }}. </span> {% if product_obj_list.has_next %} <a href="?page={{ product_obj_list.next_page_number }}">next</a> {% endif %} </span> </div> </body> </html>
示例2 改写Paginator
# -*- coding:utf-8 -*- from django.core.paginator import Paginator class CustomPaginator(Paginator): # 使用方法paginator = CustomPaginator(current_page,per_pager_num,obj_list,per_page) # current_page :: 当前页面 # per_pager_num :: 显示多少个页码 # obj_list :: 对象列表,显示的主体 # per_page :: 每页多少条目 def __init__(self, current_page, per_pager_num, *args, **kwargs): # per_pager_num 显示的页码数量 self.current_page = int(current_page) self.per_pager_num = int(per_pager_num) super(CustomPaginator, self).__init__(*args, **kwargs) def pager_num_range(self): ''' 自定义显示页码数 第一种:总页数小于显示的页码数 第二种:总页数大于显示页数 根据当前页做判断 a 如果当前页大于显示页一半的时候 ,往右移一下 b 如果当前页小于显示页的一半的时候,显示当前的页码数量 第三种:当前页大于总页数 :return: ''' # 第一种:总页数小于显示的页码数 if self.num_pages < self.per_pager_num: # 如果总页数只有10页,而设置了显示20个页码,则按照总页数显示 return range(1, self.num_pages + 1) # 第二种:总页数大于显示页数 根据当前页做判断 half_part = int(self.per_pager_num / 2) # a 如果当前页大于显示页一半的时候 ,往右移一下 if self.current_page <= half_part: # 当前页小于显示页码数量的一半时,比如当前页是3,显示20个页码,则显示1-20这些页码 return range(1, self.per_pager_num + 1) # b 如果当前页小于显示页的一半的时候,显示当前的页码数量 if (self.current_page + half_part) > self.num_pages: # 当前页大于显示页码数量的一半时,比如当前页是13,显示20个页码,则显示13-10=3 到 13+10=23的这3-23的页码 return range(self.num_pages - self.per_pager_num + 1, self.num_pages + 1) # 第三种:当前页大于总页数,配合EmptyPage使用,则显示最后一页及其往前20个页码 return range(self.current_page - half_part, self.current_page + half_part + 1)
from django.shortcuts import render from django.views import View from . import models from .utils.pager import CustomPaginator from django.core.paginator import PageNotAnInteger,EmptyPage class Index(View): def get(self,request): product_obj_list = models.Product.objects.all() page = request.GET.get("page") paginator = CustomPaginator(page,20,product_obj_list,10) try: product_obj_list_new = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. product_obj_list_new = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. product_obj_list_new = paginator.page(paginator.num_pages) context = { "product_obj_list":product_obj_list_new } return render(request,"page.html",context)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ol> {% for product_obj in product_obj_list %} {# Each "contact" is a Contact model object.#} <li>{{ product_obj }}</li> {% endfor %} </ol> <div class="pagination"> <span class="step-links"> {% if product_obj_list.has_previous %} <a href="?page={{ product_obj_list.previous_page_number }}">previous</a> {% endif %} {% for number in product_obj_list.paginator.pager_num_range %} {% if number == product_obj_list.number %} <a href="?page={{ number }}" style="font-size: 33px">{{ number }}</a> {% else %} <a href="?page={{ number }}" >{{ number }}</a> {% endif %} {% endfor %} {% if product_obj_list.has_next %} <a href="?page={{ product_obj_list.next_page_number }}">next</a> {% endif %} <span>({{ product_obj_list.number }}/{{ product_obj_list.paginator.num_pages }})</span> </span> </div> </body> </html>
示例3 自定义pager组件
示例3.1 objs与pager各自单独使用
class PageInfo(object): def __init__(self,current_page,all_count,base_url,per_page=10,max_show_page=11): self.per_page = per_page self.all_count = all_count self._current_page = current_page self.max_show_page = max_show_page self.base_url = base_url @property def actual_current_page(self): """ 涉及到(<=0,<0<=all_page,>all_page) :return: """ try: current_page = int(self._current_page) if current_page > self.all_page: current_page = self.all_page elif current_page <= 0: current_page = 1 except Exception as e: current_page = 1 return current_page @property def all_page(self): all_page, plus = divmod(self.all_count, self.per_page) if plus: all_page += 1 return all_page @property def start(self): return (self.actual_current_page-1) * self.per_page @property def end(self): return self.actual_current_page * self.per_page @property def pager_range(self): """ 显示的页码范围 :return: (begin,stop) """ half = (self.max_show_page) // 2 # 如果数据总页数 < 11 if self.all_page < self.max_show_page: begin = 1 stop = self.all_page + 1 # 如果数据总页数 > 11 else: # 如果当前页 <= 5,永远显示1,11 if self.actual_current_page <= half: begin = 1 stop = self.max_show_page + 1 else: if self.actual_current_page + half > self.all_page: # begin = self.actual_current_page - half begin = self.all_page - self.max_show_page + 1 stop = self.all_page + 1 else: begin = self.actual_current_page - half stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self): # v = '<a href="/custom.html?page=1">1</a>' # return v page_list = [] begin, stop = self.pager_range # 上一页按钮 if self.actual_current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: prev = '<li><a href="{}?page={}">上一页</a></li>'.format(self.base_url,self.actual_current_page-1) page_list.append(prev) # 页码按钮 for i in range(begin,stop): if i == self.actual_current_page: tmp = '<li class="active"><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i) else: tmp = '<li><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i) page_list.append(tmp) # if self.actual_current_page >= self.all_pager: # after = '<li><a href="#">下一页</a></li>' # else: # after = '<li><a href="{}?page={}">下一页</a></li>'.format(self.base_url,self.actual_current_page+1) # page_list.append(after) # 下一页按钮 if self.actual_current_page >= self.all_page: after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( start=self.start+1 if self.start<self.all_count else self.all_count, end=self.end if self.end<self.all_count else self.all_count, total=self.all_count) else: after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( url=self.base_url, next_page=self.actual_current_page+1, start=self.start+1 if self.start<self.all_count else self.all_count, end=self.end if self.end<self.all_count else self.all_count, total=self.all_count ) page_list.append(after) return " ".join(page_list)
from .utils.pager2 import PageInfo from django.shortcuts import render from django.views import View from . import models class Index(View): def get(self,request): page = request.GET.get("page") product_obj_list = models.Product.objects.all() all_count = product_obj_list.count() page_info = PageInfo(page,all_count,"") product_obj_list_new = product_obj_list[page_info.start:page_info.end] context = { "product_obj_list":product_obj_list_new, "pager":page_info, } return render(request,"page.html",context)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css"> </head> <body> <ol> {% for product_obj in product_obj_list %} {# Each "contact" is a Contact model object.#} <li>{{ product_obj }}</li> {% endfor %} </ol> <nav aria-label="Page navigation"> <ul class="pagination"> {{ pager.pager_str|safe }} </ul> </nav> {{ pager.pager_str|safe }} </body> </html>
示例3.2 objs封装到pager里
# -*- coding:utf-8 -*- class PageInfo(object): def __init__(self,items,current_page,base_url,per_page=10,max_show_page=11): self._items = items self.per_page = per_page self.all_count = self._items.count() self._current_page = current_page self.max_show_page = max_show_page self.base_url = base_url @property def items(self): return self._items[self.start:self.end] @property def actual_current_page(self): """ 涉及到(<=0,<0<=all_page,>all_page) :return: """ try: current_page = int(self._current_page) if current_page > self.all_page: current_page = self.all_page elif current_page <= 0: current_page = 1 except Exception as e: current_page = 1 return current_page @property def all_page(self): all_page, plus = divmod(self.all_count, self.per_page) if plus: all_page += 1 return all_page @property def start(self): return (self.actual_current_page-1) * self.per_page @property def end(self): return self.actual_current_page * self.per_page @property def pager_range(self): """ 显示的页码范围 :return: (begin,stop) """ half = (self.max_show_page) // 2 # 如果数据总页数 < 11 if self.all_page < self.max_show_page: begin = 1 stop = self.all_page + 1 # 如果数据总页数 > 11 else: # 如果当前页 <= 5,永远显示1,11 if self.actual_current_page <= half: begin = 1 stop = self.max_show_page + 1 else: if self.actual_current_page + half > self.all_page: # begin = self.actual_current_page - half begin = self.all_page - self.max_show_page + 1 stop = self.all_page + 1 else: begin = self.actual_current_page - half stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self): # v = '<a href="/custom.html?page=1">1</a>' # return v page_list = [] begin, stop = self.pager_range # 上一页按钮 if self.actual_current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: prev = '<li><a href="{}?page={}">上一页</a></li>'.format(self.base_url,self.actual_current_page-1) page_list.append(prev) # 页码按钮 for i in range(begin,stop): if i == self.actual_current_page: tmp = '<li class="active"><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i) else: tmp = '<li><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i) page_list.append(tmp) # if self.actual_current_page >= self.all_pager: # after = '<li><a href="#">下一页</a></li>' # else: # after = '<li><a href="{}?page={}">下一页</a></li>'.format(self.base_url,self.actual_current_page+1) # page_list.append(after) # 下一页按钮 if self.actual_current_page >= self.all_page: after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( start=self.start+1 if self.start<self.all_count else self.all_count, end=self.end if self.end<self.all_count else self.all_count, total=self.all_count) else: after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( url=self.base_url, next_page=self.actual_current_page+1, start=self.start+1 if self.start<self.all_count else self.all_count, end=self.end if self.end<self.all_count else self.all_count, total=self.all_count ) page_list.append(after) return " ".join(page_list)
from .utils.pager2 import PageInfo from django.shortcuts import render from django.views import View from . import models class Index(View): def get(self,request): page = request.GET.get("page") product_obj_list = models.Product.objects.all() # all_count = product_obj_list.count() page_info = PageInfo(product_obj_list,page,"") # product_obj_list_new = product_obj_list[page_info.start:page_info.end] # 封装到pager里 context = { # "product_obj_list":product_obj_list_new, "pager":page_info, } return render(request,"page.html",context)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css"> </head> <body> <ol> {# {% for product_obj in product_obj_list %}#} {% for product_obj in pager.items %} {# Each "contact" is a Contact model object.#} <li>{{ product_obj }}</li> {% endfor %} </ol> <nav aria-label="Page navigation"> <ul class="pagination"> {{ pager.pager_str|safe }} </ul> </nav> {{ pager.pager_str|safe }} </body> </html>
示例3.3 增加url里的QueryDict
class PageInfo(object): def __init__(self,items,current_page,base_url,page_param_dict,per_page=10,max_show_page=11): self._items = items self.per_page = per_page self.all_count = self._items.count() self._current_page = current_page self.max_show_page = max_show_page self.base_url = base_url self.page_param_dict = page_param_dict @property def items(self): return self._items[self.start:self.end] @property def actual_current_page(self): """ 涉及到(<=0,<0<=all_page,>all_page) :return: """ try: current_page = int(self._current_page) if current_page > self.all_page: current_page = self.all_page elif current_page <= 0: current_page = 1 except Exception as e: current_page = 1 return current_page @property def all_page(self): all_page, plus = divmod(self.all_count, self.per_page) if plus: all_page += 1 return all_page @property def start(self): return (self.actual_current_page-1) * self.per_page @property def end(self): return self.actual_current_page * self.per_page @property def pager_range(self): """ 显示的页码范围 :return: (begin,stop) """ half = (self.max_show_page) // 2 # 如果数据总页数 < 11 if self.all_page < self.max_show_page: begin = 1 stop = self.all_page + 1 # 如果数据总页数 > 11 else: # 如果当前页 <= 5,永远显示1,11 if self.actual_current_page <= half: begin = 1 stop = self.max_show_page + 1 else: if self.actual_current_page + half > self.all_page: # begin = self.actual_current_page - half begin = self.all_page - self.max_show_page + 1 stop = self.all_page + 1 else: begin = self.actual_current_page - half stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self): # v = '<a href="/custom.html?page=1">1</a>' # return v page_list = [] begin,stop = self.pager_range # 上一页按钮 if self.actual_current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: self.page_param_dict["page"] = self.actual_current_page-1 prev = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url,self.page_param_dict.urlencode()) page_list.append(prev) # 页码按钮 for i in range(begin,stop): self.page_param_dict["page"] = i if i == self.actual_current_page: tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i) else: tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i) page_list.append(tmp) # 下一页按钮 if self.actual_current_page >= self.all_page: after = '<li><a href="#">下一页</a></li>' else: self.page_param_dict["page"] = self.actual_current_page+1 after = '<li><a href="{}?{}">下一页</a></li>'.format(self.base_url,self.page_param_dict) page_list.append(after) # if self.actual_current_page >= self.all_pager: # after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( # start=self.start+1 if self.start<self.all_count else self.all_count, # end=self.end if self.end<self.all_count else self.all_count, # total=self.all_count) # else: # after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( # url=self.base_url, # next_page=self.actual_current_page+1, # start=self.start+1 if self.start<self.all_count else self.all_count, # end=self.end if self.end<self.all_count else self.all_count, # total=self.all_count # ) # page_list.append(after) return " ".join(page_list)
from .utils.pager2 import PageInfo from django.shortcuts import render from django.views import View from . import models from django.http.request import QueryDict class Index(View): def get(self,request): product_obj_list = models.Product.objects.all() page = request.GET.get("page") q = QueryDict(mutable=True) # mutable,可改变的。而request.GET是immutable的。 q.update(request.GET) page_info = PageInfo(product_obj_list,page,"",q) # product_obj_list_new = product_obj_list[page_info.start:page_info.end] # 把这一段封装到PageInfo里了 context = { # "product_obj_list":product_obj_list_new, "pager":page_info, } return render(request,"page.html",context)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css"> </head> <body> <ol> {% for product_obj in pager.items %} {# Each "contact" is a Contact model object.#} <li>{{ product_obj }}</li> {% endfor %} </ol> <nav aria-label="Page navigation"> <ul class="pagination"> {{ pager.pager_str|safe }} </ul> </nav> {{ pager.pager_str|safe }} </body> </html>
增加首页、末页
class PageInfo(object): def __init__(self,items,current_page,base_url,page_param_dict,per_page=10,max_show_page=11): self._items = items self.per_page = per_page self.all_count = self._items.count() self._current_page = current_page self.max_show_page = max_show_page self.base_url = base_url self.page_param_dict = page_param_dict @property def items(self): return self._items[self.start:self.end] @property def actual_current_page(self): """ 涉及到(<=0,<0<=all_page,>all_page) :return: """ try: current_page = int(self._current_page) if current_page > self.all_page: current_page = self.all_page elif current_page <= 0: current_page = 1 except Exception as e: current_page = 1 return current_page @property def all_page(self): all_page, plus = divmod(self.all_count, self.per_page) if plus: all_page += 1 return all_page @property def start(self): return (self.actual_current_page-1) * self.per_page @property def end(self): return self.actual_current_page * self.per_page @property def pager_range(self): """ 显示的页码范围 :return: (begin,stop) """ half = (self.max_show_page) // 2 # 如果数据总页数 < 11 if self.all_page < self.max_show_page: begin = 1 stop = self.all_page + 1 # 如果数据总页数 > 11 else: # 如果当前页 <= 5,永远显示1,11 if self.actual_current_page <= half: begin = 1 stop = self.max_show_page + 1 else: if self.actual_current_page + half > self.all_page: # begin = self.actual_current_page - half begin = self.all_page - self.max_show_page + 1 stop = self.all_page + 1 else: begin = self.actual_current_page - half stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self): # v = '<a href="/custom.html?page=1">1</a>' # return v page_list = [] begin,stop = self.pager_range # 上一页按钮 if self.actual_current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: self.page_param_dict["page"] = self.actual_current_page-1 prev = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url,self.page_param_dict.urlencode()) page_list.append(prev) self.page_param_dict['page'] = 1 first = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.page_param_dict.urlencode()) page_list.append(first) # 页码按钮 for i in range(begin,stop): self.page_param_dict["page"] = i if i == self.actual_current_page: tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i) else: tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i) page_list.append(tmp) self.page_param_dict['page'] = self.all_page last = '<li><a href="%s?%s">末页</a></li>' % (self.base_url, self.page_param_dict.urlencode()) page_list.append(last) # 下一页按钮 if self.actual_current_page >= self.all_page: after = '<li><a href="#">下一页</a></li>' else: self.page_param_dict["page"] = self.actual_current_page+1 after = '<li><a href="{}?{}">下一页</a></li>'.format(self.base_url,self.page_param_dict) page_list.append(after) # if self.actual_current_page >= self.all_pager: # after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( # start=self.start+1 if self.start<self.all_count else self.all_count, # end=self.end if self.end<self.all_count else self.all_count, # total=self.all_count) # else: # after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format( # url=self.base_url, # next_page=self.actual_current_page+1, # start=self.start+1 if self.start<self.all_count else self.all_count, # end=self.end if self.end<self.all_count else self.all_count, # total=self.all_count # ) # page_list.append(after) return " ".join(page_list)
class Page(object): def __init__(self, current_page, all_count, base_url, query_params, per_page=10, pager_page_count=11): """ 分页初始化 :param current_page: 当前页码 :param per_page: 每页显示数据条数 :param all_count: 数据库中总条数 :param pager_page_count: 页面上最多显示的页码数量 """ self.base_url = base_url self.query_params = query_params try: self.current_page = int(current_page) if self.current_page <= 0: raise Exception() except Exception as e: self.current_page = 1 self.per_page = per_page self.all_count = all_count self.pager_page_count = pager_page_count pager_count, b = divmod(all_count, per_page) if b != 0: pager_count += 1 self.pager_count = pager_count half_pager_page_count = int(pager_page_count / 2) self.half_pager_page_count = half_pager_page_count @property def start(self): """ 数据获取值起始索引 :return: """ return (self.current_page - 1) * self.per_page @property def end(self): """ 数据获取值结束索引 :return: """ return self.current_page * self.per_page def page_html(self): """ 生成HTML页码 :return: """ # 如果数据总页码pager_count<11 pager_page_count if self.pager_count < self.pager_page_count: pager_start = 1 pager_end = self.pager_count else: # 数据页码已经超过11 # 判断: 如果当前页 <= 5 half_pager_page_count if self.current_page <= self.half_pager_page_count: pager_start = 1 pager_end = self.pager_page_count else: # 如果: 当前页+5 > 总页码 if (self.current_page + self.half_pager_page_count) > self.pager_count: pager_end = self.pager_count pager_start = self.pager_count - self.pager_page_count + 1 else: pager_start = self.current_page - self.half_pager_page_count pager_end = self.current_page + self.half_pager_page_count page_list = [] if self.current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: self.query_params['page'] = self.current_page - 1 prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url,self.query_params.urlencode()) page_list.append(prev) self.query_params['page'] = 1 first = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.query_params.urlencode()) page_list.append(first) for i in range(pager_start, pager_end + 1): self.query_params['page'] = i if self.current_page == i: tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % ( self.base_url, self.query_params.urlencode(), i,) else: tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,) page_list.append(tpl) self.query_params['page'] = self.pager_count last = '<li><a href="%s?%s">末页</a></li>' % (self.base_url, self.query_params.urlencode()) page_list.append(last) if self.current_page >= self.pager_count: nex = '<li><a href="#">下一页</a></li>' else: self.query_params['page'] = self.current_page + 1 nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),) page_list.append(nex) page_str = "".join(page_list) return page_str
参考or转发
https://www.cnblogs.com/kongzhagen/p/6640975.html
https://www.cnblogs.com/nulige/p/6558207.html