Django3 前后端分离的分页方法(无需计算省略号)

        分页最麻烦的应该是计算省略号部分,并且很多人不明白到底前端分页还是后端分页,本人页尝试过很多方法,但整个过程和计算是真的太麻烦,看着脑壳疼,想着更疼

        经过很多探索和尝试后,发现Django3.2版本新增一个get_elided_page_range()方法,这个就是后端为我们分页后并得到两边的省略号对象,官方文档如下

        分页器 | Django 文档 | Django

 具体用法:

后端

1.创建一个文件:Pagination.py,以后所有的分页都可以调用它。

 2.在Pagination.py编写一个新的Custom_Paginator(obj, page, page_size)

#引入Django自带的Paginator
from django.core.paginator import Paginator

def Custom_Paginator(obj, page, page_size):

    #将接收到的obj变量按照page_size分页
    paginator = Paginator(obj, page_size)

    #得到当前page的数据列表
    page_of_obj = paginator.get_page(page)
    
    #上一页
    has_previous = page_of_obj.has_previous()
    
    #下一页
    has_next = page_of_obj.has_next()
    
    #当前页码
    current_page_num = page_of_obj.number

    #总页数
    total_page = paginator.num_pages  # 总页数
    
    #数据记录总数
    count = paginator.count
    
    #这里判断左右两边的页码小于最小页数或大于最大页数
    if current_page_num - 1 <= 0:
        prevous_page_num = 1
    else:
        prevous_page_num = current_page_num - 1

    if current_page_num + 1 >= total_page:
        next_page_num = total_page
    else:
        next_page_num = current_page_num + 1

    #重点!!!这里判断两遍的省略号,用get_elided_page_range()方法,给它提供当前页码
    page_range = list(paginator.get_elided_page_range(number=page))
    if current_page_num * page_size - page_size == 0:
        current_start_num = 1
    else:
        current_start_num = current_page_num * page_size - page_size
    if current_page_num * page_size > count:
        current_end_num = count
    else:
        current_end_num = current_page_num * page_size
    
    #封装一下数据
    data = {
        #注意这里得到的当前页码的数据列表是QuerySet,不能直接返回前端,会报错
        #还需要拿到data后简单转换一下
        'objects_list': page_of_obj, 
        'has_previous': has_previous,
        'has_next': has_next,
        'page_range': page_range,
        'elided': page_of_obj.paginator.ELLIPSIS,
        'current_page_num': current_page_num,
        'prevous_page_num': prevous_page_num,
        'next_page_num': next_page_num,
        'current_start_num': current_start_num,
        'current_end_num': current_end_num,
        'total_page': total_page,
        'count': count,
    }

    return data

3.拿到数据后, 编写View.py

#引入刚刚写的方法
From .Pagination import Custom_Paginator

class get_obj_list(APIView):
    def get(self, request):
        page = int(request.GET.get('page', 1))
        page_size = 30

        #查找数据
        list = User.objects.filter(company_code=company_code).order_by('create_time')

        data = Custom_Paginator(list, page, page_size)

        #得到的data,增加一个被转换的json数据
        data['obj_list'] = objSerializer(instance=data['objects_list'], many=True).data

        #把原来分页得到的QuerySet删除
        del data['objects_list']
        
        #这里返回数据,就不报错了
        return JsonResponse(data, json_dumps_params={'ensure_ascii': False}, safe=False)

前端

1.用一个div来放置分页数据,id=‘pages'

<ul id="pages" class="pagination mb-sm-0">
    ...这里用js写入刚刚拿到的数据
</ul>

2. 从ajax拿到数据后,编写一个html内容,需要append到<ul>标签

#每次都清空一下重新写入
$('#pages').html('')

#设置pages变量为空
var pages = ''

#下方所有判断和循环,都用+=写入到pages变量

#判断最前面的箭头,是否还有上一页,没有的话就不能点击
if ( data.has_previous ){
    var previous = data.prevous_page_num
    pages += '<li class="page-item"><a href="javascript:void(0)" onclick="'+func+'(' + previous + ')" class="page-link"><i class="mdi mdi-chevron-left"></i></a></li>'
}
else {
    pages += '<li class="page-item"><a class="disabled page-link"><i class="mdi mdi-chevron-left"></i></a></li>'
}


#判断当前页和中间部分
var page_range = data.page_range
var current_page_num = data.current_page_num
var elided = data.elided
for ( i=0; i<page_range.length;i++) {

    if (current_page_num == page_range[i]) {
        pages += '<li class="page-item active"><a href="javascript:void(0)" class="page-link">' + page_range[i] + '</a></li>'
    }
    else if ( page_range[i] == elided ) {
        pages += '<li class="page-item"><a class="page-link">' + '...' + '</a></li>'
    }
    else {
        pages += '<li class="page-item"><a href="javascript:void(0)" onclick="'+func+"(" + page_range[i] + ')" class="page-link">' + page_range[i] + '</a></li>'
     }
}


#判断最后面的箭头,是否还有下一页,没有的话就不能点击
if ( data.has_next ){
    var next = data.next_page_num
    pages += '<li class="page-item"><a href="javascript:void(0)" onclick="'+func+"(" + next + ')" class="page-link"><i class="mdi mdi-chevron-right"></i></a></li>'
}else {
    pages += '<li class="page-item"><a class="disabled page-link"><i class="mdi mdi-chevron-right"></i></a></li>'
}


#最后把pages变量写入标签
$('#pages').html(pages)

3.效果

可以根据不同的点击页数动态显示所有页数和省略号,也大大提高查询速度

这一套代码可以用在django开发的任何需要分页的位置,更精细的玩法,可以分开不同的查询去分页而互不影响。有兴趣的朋友可以共同探讨

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值