一 Paginator分页器
1 首先在数据库中生成大量数据
def index(request) book_list = [] for i in rang(1000) book = Book(title="book_%s" %i, price=i*i) book_list.append(book) Book.objects.bulk_create(book_list) # 批量插入数据
2 分页器中的主要方法
from django.core.paginator import Paginator paginator = Paginator(book_list,8) # 每页展示几条内容 print("count:",paginator.count) # 总页数 print("page_range",paginator.page_range) # 页码的列表 print("num_pages",paginator.num_pages) # 总页数 page1 = paginator.page(1) # 第1页的page对象 for i in page1 # 遍历第1页的所有数据对象 print(i) page2 = paginator.page(2) print(page2.hax_next()) # 是否有下一页 print(page2.next_page_number()) # 下一页页码 print(page2.has_pervious()) # 是否有上一页 print(page2.pervious_page_number()) # 上一页的页码
3 实现页面分页
模板:
{% if current_page.has_previous %} 先判断是否有上一页,如果没有就把'上一页'关闭 <li> <a href="?page={{ current_page_num|add:-1 }}" 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 %} {% for item in page_range %} {% if current_page_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_num|add:1 }}" aria-label="Next"> <span aria-hidden="true" class="put-right">»</span> </a> </li> {% endif %}
视图函数:
book_list = Book.objects.all() # 获取全部数据 paginator = Paginator(book_list, 10) # 每页显示10条内容 current_page_num = int(request.GET.get("page", 1)) # 当前在哪一页 if paginator.num_pages > 11: if current_page_num -5<1: page_range = range(1,11) elif current_page_num +5>paginator.num_pages: page_range=range(paginator.num_pages-11, paginator.num _pages+1) else: page_range = range(current_page_num-5, current_page_num+6) else: page_range = paginator.page_range print("count:", paginator.count) print("num_pages:", paginator.num_pages) print("page_range:", page_range) for i in page_range: print(i) try: current_page = paginator.page(current_page_num) # 第一页的数据对象 print("object_list", current_page.object_list) except: current_page = paginator.page(1) return render(request, 'index.html',locals())
二 自定义分页
1 直接在函数中实现分页
def get_data(req): if req.metho == 'GET': current_page = request.GET.get('page',1) # 获取用户传来的请求页面(相当于当前页面),默认是1 current_page = int(current_page) # 制造切片 start = (current_page - 1) * 10 end = current_page * 10 data = models.User.objects.all()[start:end] # 一次取10条数据 # 总个数 total_count = models.Classes.objects.all().count() # 用总个数和每页显示的个数相处,求商和余数,如果有余数总页码还需+1 v,a = divmod(total_count,10) # 相当于总页数 if a != 0: v+=1 # 生成页码 page_list = [] # 如果是第一页那么上一页的功能就取消 if current_page == 1: page_list.append('<a href="#">上一页</a>' %(current_page-1) else: page_list.append('<a href="/index?page=%s">上一页</a>' %(current_page-1) # 判断并生成page_range if v <= 11: pager_range_start =1 ager_range_end = v else: if current_page <6: pager_range_start = 1 pager_range_end = 11 +1 else: pager_range_start = current_page -5 pager_range_end = current_page +6 if pager_range_end > v: page_range_start = current_page - 10 pager_range_end = v +1 for i in range(pager_range_star,pager_range_end) if i == current_page: page_list.append('<a href="/index?page=%s" class=actice>%s</a>' %(i,i)) page_list.append('<a href="/index?page=%s">%s</a>' %(i,i)) # 如果当前页是最后一页那么下一页功能就取消 if current_page == v: page_list.append('<a href="#">下一页</a>' %(current_page+1) else: page_list.append('<a href="/index?page=%s">下一页</a>' %(current_page+1) pager = "".join(pager_list) return render(request,{'data':data,'str_page':pager})
2 将自定义的分页器封装成一个类
class PagerHandler: def __inin__(self,total_count,current_page, base_url. per_page=10): self.total_count = total_count self.current_page = current_page self.base_url = base_url self.per_page = per_page def db_start(self): return (self.current_page -1) * self.per_page def db_end(self): return (self.current_page) * self.per_page def tootal_page(self): v,a = divmod(total_count,10) # 相当于总页数 if a != 0: v+=1 return v def pager_str(self): v = self.tootal_page() # 生成页码 page_list = [] # 如果是第一页那么上一页的功能就取消 if self.current_page == 1: page_list.append('<a href="#">上一页</a>' %(self.current_page-1) else: page_list.append('<a href="/%s?page=%s">上一页</a>' %(self.base_url,self.current_page-1) # 判断并生成page_range if v <= 11: pager_range_start =1 pager_range_end = v else: if current_page <6: pager_range_start = 1 pager_range_end = 11 +1 else: pager_range_start = self.current_page -5 pager_range_end = self.current_page +6 if pager_range_end > v: page_range_start = self.current_page - 10 pager_range_end = v +1 for i in range(pager_range_star,pager_range_end) if i == self.current_page: page_list.append('<a href="/%s?page=%s" class=actice>%s</a>' %(self.base_url,i,i)) page_list.append('<a href="/%s?page=%s">%s</a>' %(self.base_url,i,i)) # 如果当前页是最后一页那么下一页功能就取消 if self.current_page == v: page_list.append('<a href="#">下一页</a>' %(self.current_page+1) else: page_list.append('<a href="/%s?page=%s">下一页</a>' %(self.base_url,self.current_page+1) pager = "".join(pager_list) return pager
3 在视图函数中调用
def index(request) if request.method == 'GET': current_page = request.GET.get('page',1) current_page = int(current_page) # 数据总数 total_count = models.Classes.objects.all().count() page_obj = PagerHandler(total_count,current_page,'/index/') pager = page_obj.pager_str() data = models.Classes.objects.all()[page_obj.db_start():page_obj.db_end()]
return render(request,'index.html',{'data':data,'pager':pager})
4 也页面中保留过滤条件班分页组件
class Pagination: def __init__(self, data_num, current_page, params, url_prefix, per_page=10, max_show=11): """ 进行初始化. :param data_num: 数据总数 :param current_page: 当前页 :param url_prefix: 生成的页码的链接前缀 :param per_page: 每页显示多少条数据 :param max_show: 页面最多显示多少个页码 """ self.data_num = data_num self.per_page = per_page self.max_show = max_show self.url_prefix = url_prefix # 把页码数算出来 self.page_num, more = divmod(data_num, per_page) if more: self.page_num += 1 try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 # 如果URL传过来的页码数是负数 if self.current_page <= 0: self.current_page = 1 # 如果URL传过来的页码数超过了最大页码数 elif self.current_page > self.page_num: self.current_page = self.page_num # 默认展示最后一页 # 页码数的一半 算出来 self.half_show = self.max_show // 2 # 如果数据总页码self.page_num<11 pager_page_count if self.page_num <= self.max_show: self.page_start = 1 self.page_end = self.page_num else: # 数据页码已经超过11 # 判断: 如果当前页 <= 5 self.half_show if self.current_page <= self.half_show: self.page_start = 1 self.page_end = self.max_show else: # 如果: 当前页+5 > 总页码 if (self.current_page + self.half_show) > self.page_num: self.page_start = self.page_num - self.max_show + 1 self.page_end = self.page_num else: self.page_start = self.current_page - self.half_show self.page_end = self.current_page + self.half_show import copy self.params = params # {"page":"12","title_startwith":"py","id__gt":"5"} @property def start(self): # 数据从哪儿开始切 return (self.current_page - 1) * self.per_page @property def end(self): # 数据切片切到哪儿 return self.current_page * self.per_page def page_html(self): # 生成页码 l = [] # 加一个首页 first_page = self.params first_page['page'] = 1 l.append('<li><a href="{}?{}">首页</a></li>'.format(self.url_prefix, first_page.urlencode())) # 加一个上一页 if self.current_page == 1: l.append('<li class="disabled" ><a href="#">«</a></li>'.format(self.current_page)) else: self.params['page'] = self.current_page - 1 l.append('<li><a href="{}?{}">«</a></li>'.format(self.url_prefix, self.params.urlencode())) for i in range(self.page_start, self.page_end + 1): self.params['page'] = i if i == self.current_page: tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.url_prefix, self.params.urlencode(), i) else: tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.url_prefix, self.params.urlencode(), i) l.append(tmp) # 加一个下一页 if self.current_page == self.page_num: l.append('<li class="disabled"><a href="#">»</a></li>'.format(self.current_page)) else: self.params['page'] = self.current_page + 1 l.append('<li><a href="{}?{}">»</a></li>'.format(self.url_prefix, self.params.urlencode())) # 加一个尾页 last_page = self.params last_page['page'] = self.page_num l.append('<li><a href="{}?{}">尾页</a></li>'.format(self.url_prefix, last_page.urlencode())) return "".join(l)