Django之paginator分页功能及重写Paginator类实现自定义分页

网页中经常会用到分页,django中自带的paginator为我们很好的实现了分页功能。虽然其中还有些功能待完善,例如paginator会为我们将所有的页码全部展现出来,如果页码过多的话,全部显示就不太合理了,此时我们可以通过重写paginator类去实现我们想要的结果。

想要使用分页功能首先需要导入:

from django.core.paginator import Paginator

使用:

paginator = Paginator(List_info,num) # List_info表示传入的总数据,num表示每页显示的数据

其中paginator对象含有的属性:

per_page:每页显示的数据条数
count:数据总数
num_pages:总页数
page_range:总页数索引范围
page:page对象

page对象含有的方法:

has_next:判断是否有下一页
has_previous:判断是否有上一页
objects_list:分页之后的数据列表
next_page_number:下一页页码
previous_page_number:上一页页码
number:当前页(属性)
paginator:paginator对象

下面我们写一个简单的分页展示:

后端代码:

class PaginatorView(View):
    def get(self,request):
        current_page = request.GET.get("page",1)
        all_name_obj = PaginatorTest.objects.all()
        paginator = Paginator(all_name_obj,10)
        page = paginator.page(current_page)
        return render(request,"paginator_list.html",locals())

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
    <ul>
        {% for name_obj in page %}
            <li>{{ name_obj.name }}</li>
        {% endfor %}
    </ul>
    <div>
        <nav aria-label="Page navigation">
          <ul class="pagination">
          {% if page.has_previous %}
            <li class="active">
              <a href="/buyer/paginator/?page={{ page.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">上一页</span>
              </a>
            </li>
          {% else %}
            <li class="disabled">
              <a href="javascript:void(0);" aria-label="Previous">
                <span aria-hidden="true">上一页</span>
              </a>
            </li>
          {% endif %}
          {% for current_page in paginator.page_range %}
            {% if page.number == current_page %}
                <li class="active">
                  <a href="/buyer/paginator/?page={{ current_page }}">{{ current_page }}</a>
                </li>
            {% else %}
                <li>
                  <a href="/buyer/paginator/?page={{ current_page }}">{{ current_page }}</a>
                </li>
            {% endif %}
          {% endfor %}
          {% if page.has_next %}
            <li class="active">
              <a href="/buyer/paginator/?page={{ page.next_page_number }}" aria-label="Previous">
                <span aria-hidden="true">下一页</span>
              </a>
            </li>
          {% else %}
            <li class="disabled">
              <a href="javascript:void(0);" aria-label="Previous">
                <span aria-hidden="true">下一页</span>
              </a>
            </li>
          {% endif %}
          </ul>
        </nav>
    </div>
</body>
</html>

此时页面展示如下:

可以看到,页面中将所有的页码全部展示出来了,显示效果很不好看,如果想要只展示当前页的前几页页码和后几页页码应该如何实现呢,其他的页面用“...”代替,同时第一页和最后一页永远显示应该如何实现呢?

直接上代码:

class MyPaginator(Paginator): # 继承Paginator
    def __init__(self,object_list, per_page, show_count=3, orphans=0, allow_empty_first_page=True): # show_count代表要展示的当前页之前或之后的页码数,默认展示3页
        super().__init__(object_list, per_page, orphans, allow_empty_first_page) #继承父类的属性和方法
        self.show_count = show_count
        self.has_previous_more = True #定义show_count之前是否还有更多页码
        self.has_next_more = True #定义show_count之后是否还有更多页码
    
    #覆写page方法
    def page(self, number):
        self.number = int(number)
        #判断当前页之前是否还有show_count显示的页码数
        if self.number <= self.show_count + 2:
            self.has_previous_more = False
            self.previous_range = range(1,self.number)
        else:
            self.previous_range = range(self.number - self.show_count, self.number)
        #判断当前页之后是否还有show_count显示的页码数
        if self.number >= self.num_pages - self.show_count - 1:
            self.has_next_more = False
            self.next_range = range(self.number + 1, self.num_pages + 1)
        else:
            self.next_range = range(self.number + 1, self.number + self.show_count + 1)
        return super().page(number)



class PaginatorView(View):
    def get(self,request):
        current_page = request.GET.get("page",1)
        all_name_obj = PaginatorTest.objects.all()
        paginator = MyPaginator(all_name_obj,10) #可增加第三个参数确定当前页之前或之后展示的页码数
        page = paginator.page(current_page)
        return render(request,"paginator_list.html",locals())

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
    <ul>
        {% for name_obj in page %}
            <li>{{ name_obj.name }}</li>
        {% endfor %}
    </ul>
    <div>
        <nav aria-label="Page navigation">
          <ul class="pagination">
          {% if page.has_previous %}
            <li class="active">
              <a href="/buyer/paginator/?page={{ page.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">上一页</span>
              </a>
            </li>
          {% else %}
            <li class="disabled">
              <a href="javascript:void(0);" aria-label="Previous">
                <span aria-hidden="true">上一页</span>
              </a>
            </li>
          {% endif %}
          {% if paginator.has_previous_more %}
            <li><a href="/buyer/paginator/?page=1">1</a></li>
            <li><a href="javascript:void(0);">...</a></li>
          {% endif %}
          {% for previous_page in paginator.previous_range %}
            <li><a href="/buyer/paginator/?page={{ previous_page }}">{{ previous_page }}</a></li>
          {% endfor %}
          <li class="active"><a href="/buyer/paginator/?page={{ page.number }}">{{ page.number }}</a></li>
          {% for next_page in paginator.next_range %}
            <li><a href="/buyer/paginator/?page={{ next_page }}">{{ next_page }}</a></li>
          {% endfor %}
          {% if paginator.has_next_more %}
            <li><a href="javascript:void(0);">...</a></li>
            <li><a href="/buyer/paginator/?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
          {% endif %}

          {% if page.has_next %}
            <li class="active">
              <a href="/buyer/paginator/?page={{ page.next_page_number }}" aria-label="Previous">
                <span aria-hidden="true">下一页</span>
              </a>
            </li>
          {% else %}
            <li class="disabled">
              <a href="javascript:void(0);" aria-label="Previous">
                <span aria-hidden="true">下一页</span>
              </a>
            </li>
          {% endif %}
          </ul>
        </nav>
    </div>
</body>
</html>

页面效果:

这样我们就完善了django自带的paginator分页功能,可以完美展示我们想要的各种分页效果。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值