ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # 自定义 分页 分页分为两种,一种自定义,一种用自带的 >[info] ## 自定义的分页 >[danger] ##### 思路 ~~~ 1.当前页,当前页可能会被传入特别的值建议异常就是第一页 2.底栏展示页码 3.数据总个数用来计算生成多少页 4.每页展示页数 ~~~ * 首先我们利用切片,把数据分成段落显示,每一页的第一条数据是(当前页-1)*页面显示条数 ~~~ @property def start(self): ''' :return: 开始页数 ''' return (self.current_page-1)*self.page_count ~~~ * 每页最后一条数据是(当前页*显示条数) ~~~ @property def end(self): ''' :return: 结束页数 ''' return (self.current_page*self.page_count) ~~~ * 页面的总页数是总条数/页面显示页数 ~~~ @property def total_count(self): ''' :return: 总页数 ''' v, y = divmod(self.data_count,self.page_count) if y: v +=1 return v ~~~ * 页面展示的条数也就是循环次数 ~~~ 1.当总页数小于页面实际展示页数时,开始页1,结束页实际页数 2.当总页数大于页面实际展示页数时 3.第一种情况当前页小于中间页,开始页1,结束页是页面展示底栏 4.第二种情况当前页大于中间页,开始页当前页-(中间页-1)/2,结束页(当前页+1)/2 5.当然第二种的前提建立在(当前页+(中间页-1)/2)大于总页数 6.开始页总页数-底栏数-1,结束页等于总页数+1 ~~~ >[danger] ##### 代码 | 参数 |意义| | --- | --- | | current_page | 当前页 | | data_count | 数据库总条数 | | per_page_count | 每页显示条数 | | pager_num | 显示几个页码栏 | |base_url|当前连接| ~~~ from django.utils.safestring import mark_safe class Pagination(object): def __init__(self, current_page, data_count, per_page_count=1, pager_num=7): try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.data_count = data_count self.per_page_count = per_page_count self.pager_num = pager_num @property def start(self): return (self.current_page - 1) * self.per_page_count @property def end(self): return self.current_page * self.per_page_count @property def total_count(self): v, y = divmod(self.data_count, self.per_page_count) if y: v += 1 return v def page_str(self, base_url): page_list = [] if self.total_count < self.pager_num: start_index = 1 end_index = self.total_count + 1 else: if self.current_page <= (self.pager_num + 1) / 2: start_index = 1 end_index = self.pager_num + 1 else: start_index = self.current_page - (self.pager_num - 1) / 2 end_index = self.current_page + (self.pager_num + 1) / 2 if (self.current_page + (self.pager_num - 1) / 2) > self.total_count: end_index = self.total_count + 1 start_index = self.total_count - self.pager_num + 1 if self.current_page == 1: prev = '<li><a class="page" href="javascript:void(0);">上一页</a></li>' else: prev = '<li><a class="page" href="%s?p=%s">上一页</a></li>' % (base_url, self.current_page - 1,) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == self.current_page: temp = '<li class="active"><a class="page active" href="%s?p=%s">%s</a></li>' % (base_url, i, i) else: temp = '<li><a class="page" href="%s?p=%s">%s</a></li>' % (base_url, i, i) page_list.append(temp) if self.current_page >= self.total_count: nex = '<li><a class="page" href="javascript:void(0);">下一页</a></li>' else: nex = '<li><a class="page" href="%s?p=%s">下一页</a></li>' % (base_url, self.current_page + 1,) page_list.append(nex) # jump = """ # <input type='text' /><a onclick='jumpTo(this, "%s?p=");'>GO</a> # <script> # function jumpTo(ths,base){ # var val = ths.previousSibling.value; # location.href = base + val; # } # </script> # """ % (base_url,) # # page_list.append(jump) page_str = mark_safe("".join(page_list)) return page_str ~~~ >[success] 用法 ~~~ 1.取出所有条数 2.获取当前页码 3.对数据做切片 4.获取当前连接 ~~~ ~~~ def index(request): datacount = models.userInfo.objects.count() page_obj = Pagination(request.GET.get('p'),datacount) userinfo = models.userInfo.objects.all()[page_obj.start:page_obj.end] print(page_obj.start,page_obj.end) base_url = reverse('index', ) page_str = page_obj.page_str(base_url) return render(request, "index.html", { 'userinfo': userinfo, 'page_str': page_str, }) ~~~ >[success] # Django 自带的分页 >[info] ## 基本参数介绍 >[danger] ##### 引入类 ~~~ from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger ~~~ >[danger] ##### 使用 ~~~ 1.第一个参数必须为list 2.每页展示个数 paginator = Paginator(list(obj_count), 1) ~~~ * 这里面封装的方法有 ~~~ 1.per_page: 每页显示条目数量 2.count: 数据总个数 3.num_pages:总页数 4.page_range:总页数的索引范围,如: range(1, 6) 页数循环 5.page: page对象(是否具有上一页,下一页) ~~~ * page 对象有 ~~~ 1. has_next 是否有下一页 2. next_page_number 下一页页码 3. has_previous 是否有上一页 4. previous_page_number 上一页页码 5. object_list 分页之后的数据列表 6. number 当前页 7. paginator paginator对象 ~~~ >[danger] views代码 ~~~ def index(request): obj_count = models.userInfo.objects.all() paginator = Paginator(list(obj_count), 2) current_page = request.GET.get('page') try: posts = paginator.page(current_page) except EmptyPage: posts = paginator.page(paginator.num_pages) except PageNotAnInteger: posts = paginator.page(1) return render(request, 'index.html', {'posts': posts}) ~~~ >[danger] html ~~~ //是否有上一页 {% if posts.has_previous %} <a href="/index1?page={{ posts.previous_page_number }}">上一页</a> //没有上一页,不让点击 {% else %} <a href="#">上一页</a> {% endif %} //是否有下一页 {% if posts.has_next%} <a href="/index1?page={{ posts.next_page_number }}">下一页</a> //没有下一页,不让点击 {% else %} <a href="#">下一页</a> {% endif %} ~~~ * 数据展示 ~~~ <ul> {% for i in posts %} <li>{{ i }}</li> {% endfor %} </ul> ~~~ >[danger] ##### 升级版本自定制 ~~~ #保证循环的次数在规定的展示栏个数,如果设置11,循环的次数保证在11次 class CustomPaginator(Paginator): def __init__(self, current_page, per_pager_num,*args, **kwargs): ''' :param current_page: 当前页 :param per_pager_num: 底边栏展示页数 ''' self.current_page = int(current_page) self.per_pager_num = int(per_pager_num) super(CustomPaginator, self).__init__(*args, **kwargs) def page_num_range(self): #总页数小于实际展示页 if self.num_pages < self.per_pager_num: return range(1,self.num_pages+1) #part 当前总展示栏中间点5 part = int(self.per_pager_num//2) #最小页数为1防止出现负数情况 if self.current_page <= part: return range(1,self.per_pager_num+1) #最大页数为实际总页数 if(self.current_page+part)>self.num_pages: return range(self.num_pages-self.per_pager_num+1,self.num_pages+1) return range(self.current_page-part,self.current_page+part+1) ~~~ ![](https://box.kancloud.cn/6997e2cc9517cd514b32ddedb4ff25b7_691x278.png)