Django 封装页码模块

封装分页类

封装 pagination.py 类, 需要的页面导入就行

"""
自定义的分页组件, 以后如果想要使用分页组件,需要如下:

在视图函数中(views.py):

    def num_list(request):

        # 1. 根据直实需求筛选需要的数据
        queryset = models.PrettyNum.objects.all()

        # 2. 实例化分页对象
        page_object = Pagination(request, queryset)

        # 3. 返回到html的数据
        context = {
                # 分完页的数据
                'queryset': page_object.page_queryset,
                # 数据计数
                'count': queryset.count(),
                # 生成页码
                'page_string': page_object.html(),
            }
        return render(request, 'num_list.html', context=context)

在HTML页面中

    {% for obj in queryset %}
        {{ obj.xx }}
    {% endfor %}


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

"""

from django.utils.safestring import mark_safe
import copy


class Pagination(object):

    def __init__(self, request, queryset, page_size=10, page_param='page', plus=5):
        """
        :param request: 请求的对象,需要传入
        :param queryset: 符合条件的查询数据(根据这个数据进行分布处理),需要传入
        :param page_size: 每页多少条数据,如不传入默认是10条
        :param page_param: 在URL里传递的获取分页的参数,例如:/prettynum/list/?page=4
        :param plus: 显示当前选中页的 前后各几页
        """

        # 拿到浏览器 get方式传过来的page, 不需要传入
        page = request.GET.get(page_param, '1')
        # 判断页码,如果是数字,int转换
        if page.isdecimal():
            page = int(page)
        else:
            # 非数字 赋值为1
            page = 1
        # 当前页
        self.page = page
        # 每页显示的数据条数
        self.page_size = page_size
        # 显示分页数据起始值和结束值
        # 规律:当前页码-1*10 到 当前页码*10
        self.start = (page - 1) * page_size
        self.end = page * page_size
        # 分完页的数据
        # queryset 是 对象传入的参数:根据条件筛选的数据,
        # [self.start:self.end]-包含了数据起始值和结束值]
        self.page_queryset = queryset[self.start:self.end]
        # 计算总条数
        self.count = queryset.count()
        # 计算总页码 self.total_page_count    # 除法,divmod 取商和余数
        self.total_page_count, self.div = divmod(self.count, page_size)
        if self.div > 0:
            self.total_page_count += 1
        # 显示当前页的 前5页 和 后5页
        self.plus = plus

        # 拼接 url传过来的GET参数
        # 生拷贝了一份request.GET
        query_dict = copy.deepcopy(request.GET)
        # 修改源码,允许修改
        from django.http.request import QueryDict
        query_dict._mutable = True
        # 包含了原来的url参数(比如:搜索条件)
        self.query_dict = query_dict
        # 增加的带页码的参数
        self.page_param = page_param

    def html(self):
        # 计算出,
        # 如果总页码小于等于 11 页,就在一页显示完所有页码,合计11页码
        if self.total_page_count <= self.plus * 2 + 1:
            # 起始页
            start_page = 1
            # 结尾页
            end_page = self.total_page_count
        # 超过11页 显示前5,当前和后5
        else:
            # 当前页小于5,防止起始页出现 -负数
            if self.page <= self.plus:
                start_page = 1
                end_page = self.plus * 2 + 1
            else:
                # 当前页 +5 > 总页码的情况:
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.page - self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus

        # 后台需要生成的html标签页码
        page_str_list = []  # [‘li标签1’,'li标签2',......'li标签19']

        # 首页
        self.query_dict.setlist(self.page_param, [1])
        page_str_list.append('<li ><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))

        # 上一页   page 是当前页 -1前一页 , 格式化字符串
        if self.page > 1:
            self.query_dict.setlist(self.page_param, [self.page - 1])
            prev = '<li ><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li ><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(prev)

        # 页面
        # range 前取后不取,所以+1
        # for i in range(1, total_page_count+1):
        for i in range(start_page, end_page + 1):
            self.query_dict.setlist(self.page_param, [i])
            # ?page=值
            # 如果循环到当前页,增加一个 class="active" 样式,高亮显示激活状态
            if i == self.page:
                ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            else:
                ele = '<li ><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            page_str_list.append(ele)

        # 下一页 当前页小于总页数
        if self.page < self.total_page_count:
            self.query_dict.setlist(self.page_param, [self.page + 1])
            next = '<li ><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            next = '<li ><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(next)

        # 尾页
        self.query_dict.setlist(self.page_param, [self.total_page_count])
        page_str_list.append('<li ><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))

        # 跳转
        skip_string = """
                <li>
                    <form method="get" style="float: left; margin-left: -1px">
                        <input name="page"
                               style="position: relative; float: left; display: inline-block;width: 80px; border-radius: 0"
                               type="text" class="form-control" placeholder="页码">
                        <button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button>
                    </form>
                </li>
                """

        page_str_list.append(skip_string)

        # diango 框架下,直接写html格式,需要标记 mark_safe
        # from django.utils.safestring import mark_safe
        # 标记安全的字符串转html标签 make_safe 需要导入
        # join() 将元素按照分隔符「拼接」成新的字符串, ''空分隔符
        # 传到前端
        page_string = mark_safe(''.join(page_str_list))
        # 将 page_string 返回到前端
        return page_string

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值