Django 分页器 Paginator

分页器要导入的包

from django.core.paginator import Paginator Paginator 就是分页器导入的模块
from django.core.paginator import EmptyPage EmptyPage 是一个错误异常,用于超出页数范围外而抛出的异常

分页器的常用方法

    paginator = Paginator(bks, 7)  #Paginator 添加所有返回的数据对象,和每页展示多少数据的int参数
    paginator.count                # 数据页数
    paginator.num_pages            # 按照上面7条数据分后的总页数
    paginator.page_range           # 页码的列表
-----------------------------------------------------------------------------
    page1 = paginator.page(1)      # 获取第一页的数据对象
    for i in page1:                #遍历page1的所有数据,效果和 object_list 一样,只不过object_list是列表形式
       print(i)


    page1.object_list              #page1的所有数据 列表形式
--------------------------------------------------------------------------------

    page1.has_next()              #是否有下一页
    page1.has_other_pages()       #是否有下一页或者上一页
    page1.has_previous()          #是否有上一页
    page1.next_page_number()      #获取下一页页码 和 has_next一起用
    page1.previous_page_number()   #获取下一页页码 和 has_previous一起用

用分页器分页显示数据的数据

先利用models.object.bulk_create()进行批量插入数据

bk_list=[]
    for i in range(1,100):
        bk = models.test.objects.create(name="python-%i"%(i),price=i,)
        bk_list.append(bk)
    try:
        #不用try会提示primary_key重复,不知道原因在哪里,数据可以正常插入
        models.test.objects.bulk_create(bk_list)
    except Exception:
       pass

效果图

分页展示数据

用分页器展示下面的选择页数

效果图

用分页器展示下面的选择页数添加选中的页数底色添加效果

给选中的当前页数添加class ="active"就行.

效果图

用分页器对于上一页 下一页的条件设定

对于上一页 下一页 要实现 分别会进行页数加减,但是也要实现第一页的时候点击上一页无效,最后一页的时候点击下一页无效
页数加减,可以用蒙版语法的过滤器add实现 上一页就add:-1,下一页就add:1,也可以使用当前页的对象的next_page_number 和previous_page_number方法

用分页器只展示11页数据,其他多余的隐藏动态显示


效果展示

大致思路如下:
获取总页数:paginator.num_pages 假设当前页是current_page,总页数是total_page
如果当前点击页数是1,那么就显示1-11页,页数直接返回一个range(1,12)
如果当前点击页数是最后一页,那么就返回区间range(total_page-11,total_page+1)
如果点击的是中间的页数,返回区间(current_page-5,current_page+6)
这里还要考虑2个情况 如果current_page-5<1的时候和current_page+6>total_page的时候.

自定义实现的分页器

django内置分页器功能不是很强大.下面是一个封装的分页器,可以搭配form组件进行使用
视图函数

def customer_list(request):
        # 所有数据
        queryset = models.Customer.objects.filter(active=1).select_related('level')
        pager = Pagination(request, queryset)
        context = {
            "queryset": queryset[pager.start:pager.end],
            "pager_string": obj.html()
        }
        return render(request, 'customer_list.html', context)

HTML代码

{% for obj in queryset %}
            <tr>
                <td>{{ obj.id }}</td>
                <td>{{ obj.username }}</td>
                <td>{{ obj.mobile }} </td>
                <td>{{ obj.level.title }} </td>
                <td>{{ obj.get_role_level_display }} </td>
                <td><a class="btn btn-primary" href="{% url 'customer_edit' obj.id %}">编辑</a></td>
                <td><a class="btn btn-danger del_btn" idx="{{ obj.id }}">删除</a></td>

            </tr>
        {% endfor %}



<ul class="pagination">
    {{ pager_string }}
</ul>

封装的分页器
关于self.query_dict.setlist,self.query_dict._mutable = True 看下面
https://www.cnblogs.com/Young-shi/p/15085527.html里的视图请求


如果想要以后使用分页,需要以下两个步骤:
在视图函数:
    def customer_list(request):
        # 所有数据
        queryset = models.Customer.objects.filter(active=1).select_related('level')
        pager = Pagination(request, queryset)
        context = {
            "queryset": queryset[pager.start:pager.end],
            "pager_string": obj.html()
        }
        return render(request, 'customer_list.html', context)

在页面上:
    {% for row in queryset %}
        {{row.id}}
    {% endfor %}

    <ul class="pagination">
        {{ pager_string }}
    </ul>

import copy
from django.utils.safestring import mark_safe


class Pagination(object):
    """ 分页 """

    def __init__(self, request, query_set, per_page_count=10):

        self.query_dict = copy.deepcopy(request.GET)
        self.query_dict._mutable = True

        self.query_set = query_set
        total_count = query_set.count()
        self.total_count = total_count
        # 计算出总共有多少页面
        self.total_page, div = divmod(total_count, per_page_count)
        if div:
            self.total_page += 1

        page = request.GET.get('page')
        if not page:
            page = 1
        else:
            if not page.isdecimal():
                page = 1
            else:
                page = int(page)
                if page <= 0:
                    page = 1
                else:
                    if page > self.total_page:
                        page = self.total_page
        # 封装计算分多少页
        self.page = page
        self.per_page_count = per_page_count

        self.start = (page - 1) * per_page_count
        self.end = page * per_page_count

    def html(self):
        pager_list = []
        if not self.total_page:
            return ""

        # 总页码小于11
        if self.total_page <= 11:
            start_page = 1
            end_page = self.total_page
        else:
            # 总页码比较多
            # 判断当前页 <=6: 1~11
            if self.page <= 6:
                start_page = 1
                end_page = 11
            else:
                if (self.page + 5) > self.total_page:
                    start_page = self.total_page - 10
                    end_page = self.total_page
                else:
                    start_page = self.page - 5
                    end_page = self.page + 5

        self.query_dict.setlist('page', [1])
        pager_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
        # 设置上一页标签
        if self.page > 1:
            self.query_dict.setlist('page', [self.page - 1])
            pager_list.append('<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode()))
        # 遍历产生标签
        for i in range(start_page, end_page + 1):
            self.query_dict.setlist('page', [i])
            if i == self.page:
                item = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            else:
                item = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            pager_list.append(item)
            # 设置下一页标签
        if self.page < self.total_page:
            self.query_dict.setlist('page', [self.page + 1])
            pager_list.append('<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode()))
            #设置 尾页
        self.query_dict.setlist('page', [self.total_page])
        pager_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))

        pager_list.append('<li class="disabled"><a>数据{}条{}页</a></li>'.format(self.total_count, self.total_page))
        pager_string = mark_safe("".join(pager_list))
        return pager_string

    def queryset(self):
        if self.total_count:
            return self.query_set[self.start:self.end]
        return self.query_set


posted @ 2021-09-12 18:06  零哭谷  阅读(611)  评论(0编辑  收藏  举报