自定义万能分页类

1 分页类

utils.pageinfo.py

class PageInfo(object):
    """
    通用分页类
    """

    def __init__(self, curent_page, total_page, show_page_nums, per_page_number, url_prefix):
        """
        curent_page : 当前请求页,来自于url,>0的int类型
        total_page :总页数 int类型
        show_page_nums : 显示在画面中的页码 int类型
        per_page_number : 每页显示的条目数

        """
        if isinstance(curent_page, int) and curent_page >= 1:
            self.curent_page = curent_page
        else:
            self.curent_page = 1
        self.total_page = total_page
        self.show_page_nums = show_page_nums
        self.per_page_number = per_page_number
        self.url_prefix = url_prefix
        # self.half 存储页码范围
        self.half = int(show_page_nums / 2)

    @property
    def start(self):
        return (self.curent_page - 1) * self.per_page_number

    @property
    def end(self):
        return self.curent_page * self.per_page_number

    def pagestr(self):
        page_info_list = []
        page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page=1">首页</a>')
        if self.curent_page <= 1:
            page_info_list.append(f'<a class="pageNum" href="#">上一页</a>')
        else:
            page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.curent_page - 1}">上一页</a>')
        # 如果数据总页数小于展示的页数,那么页数就从第一页~总页数
        if self.total_page <= self.show_page_nums:
            for i in range(1, self.total_page + 1):
                if i == self.curent_page:
                    page_info_list.append(f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
                else:
                    page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
        else:
            # 如果我们想显示11个页码,那么当前页的前后应该各有5条数据,为了保证当前页前面的页码不出现0或者负数,
            # 所以页码范围从1一直到需要显示到11
            if self.curent_page - self.half <= 0:
                for i in range(1, self.show_page_nums + 1):
                    if i == self.curent_page:
                        page_info_list.append(f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
                    else:
                        page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
            else:
                # 如果当前页码加上后面的页数超过了总页数,同页显示总页数前面的十条数据
                if self.curent_page + self.half >= self.total_page:
                    for i in range(self.total_page - self.show_page_nums + 1, self.total_page + 1):
                        if i == self.curent_page:
                            page_info_list.append(
                                f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
                        else:
                            page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
                else:
                    # 如果不是上面两种极限情况,就按照正常的数据前后各5页数据执行
                    for i in range(self.curent_page - self.half, self.curent_page + self.half + 1):
                        if i == self.curent_page:
                            page_info_list.append(
                                f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
                        else:
                            page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
        if self.curent_page >= self.total_page:
            page_info_list.append(f'<a class="pageNum" href="#">下一页</a>')
        else:
            page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.curent_page + 1}">下一页</a>')
        page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.total_page}">尾页</a>')
        return ''.join(page_info_list)

2 django实际应用案例

2.1 视图函数

views.py

def test(requset):
    # 获取page_number 数据
    try:
        if int(requset.GET.get("page", 1)) > 0:
            page_number = int(requset.GET.get("page", 1))
        else:
            page_number = 1
    except Exception:
        page_number = 1
    
    # 表内的数据条数
    item_count = TestTable.objects.all().count()
    # 每页显示的数据条目数
    per_page_number = 10
    # 总页数需要多少页,不足一页得也需要一页显示
    total_page,b = divmod(item_count, per_page_number)
    if b:
        total_page += 1
    # 窗口中显示得页码个数
    show_page_nums = 7
	# 实例化分页类
    page_info_obj = pageinfo.PageInfo(
        curent_page = page_number, # 当前请求页
        total_page = total_page, # 总页数
        show_page_nums = show_page_nums, # 需要显示得页数
        per_page_number = per_page_number, # 每页显示得条目数
        url_prefix = "/app01/test.html/" # 需要分页得URL
    )
    tag_list = TestTable.objects.all()[page_info_obj.start: page_info_obj.end]  # 获取分页后的列表
    return render(requset, 'test.html', {"tag_list":tag_list, "total_page_list":page_info_obj.pagestr()}) # 返回响应

2.2 数据模型

models.py

class TestTable(models.Model):
    tid = models.BigIntegerField(primary_key=True)
    tname = models.CharField(max_length=30)

表中插入得虚拟数据:
在这里插入图片描述

2.3 模板

test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pageNum {
            display: inline-block;
            padding: 5px;
            margin: 5px;
            text-decoration: none;
        }
        .active {
            background-color: cornflowerblue;
            font-weight: bold;

        }
        .ishidden {
            display: none;
        }
    </style>
</head>
<body>
<h1>变量列表</h1>

<ul>
    {% for row in tag_list %}
        <li>{{ row.tname }}</li>
    {% endfor %}

</ul>
    {{ total_page_list | safe }}
</body>
</html>

分页效果
在这里插入图片描述在这里插入图片描述
如果需要可以自己加样式,bootstrap等

Update 2022-05-25

解决了分页干扰其他参数的问题

class Pagination(object):
    def __init__(self, current_page, all_count, base_url, query_params, per_page=30, pager_page_count=11):
        """
        分页初始化
        :param current_page: 当前页码
        :param per_page: 每页显示数据条数
        :param all_count: 数据库中总条数
        :param base_url: 基础URL
        :param query_params: QueryDict对象,内部含所有当前URL的原条件
        :param pager_page_count: 页面上最多显示的页码数量
        """
        self.base_url = base_url
        try:
            self.current_page = int(current_page)
            if self.current_page <= 0:
                self.current_page = 1
        except Exception as e:
            self.current_page = 1
        query_params = query_params.copy()
        query_params._mutable = True
        self.query_params = query_params
        self.per_page = per_page
        self.all_count = all_count
        self.pager_page_count = pager_page_count
        pager_count, b = divmod(all_count, per_page)
        if b != 0:
            pager_count += 1
        self.pager_count = pager_count

        half_pager_page_count = int(pager_page_count / 2)
        self.half_pager_page_count = half_pager_page_count

    @property
    def start(self):
        """
        数据获取值起始索引
        :return:
        """
        return (self.current_page - 1) * self.per_page

    @property
    def end(self):
        """
        数据获取值结束索引
        :return:
        """
        return self.current_page * self.per_page

    def page_html(self):
        """
        生成HTML页码
        :return:
        """
        if self.all_count == 0:
            return ""

        # 如果数据总页码pager_count<11 pager_page_count
        if self.pager_count < self.pager_page_count:
            pager_start = 1
            pager_end = self.pager_count
        else:
            # 数据页码已经超过11
            # 判断: 如果当前页 <= 5 half_pager_page_count
            if self.current_page <= self.half_pager_page_count:
                pager_start = 1
                pager_end = self.pager_page_count
            else:
                # 如果: 当前页+5 > 总页码
                if (self.current_page + self.half_pager_page_count) > self.pager_count:
                    pager_end = self.pager_count
                    pager_start = self.pager_count - self.pager_page_count + 1
                else:
                    pager_start = self.current_page - self.half_pager_page_count
                    pager_end = self.current_page + self.half_pager_page_count

        page_list = []

        if self.current_page <= 1:
            prev = '<li><a href="#">上一页</a></li>'
        else:
            self.query_params['page'] = self.current_page - 1
            prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode())
        page_list.append(prev)
        for i in range(pager_start, pager_end + 1):
            self.query_params['page'] = i
            if self.current_page == i:
                tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % (
                    self.base_url, self.query_params.urlencode(), i,)
            else:
                tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,)
            page_list.append(tpl)

        if self.current_page >= self.pager_count:
            nex = '<li><a href="#">下一页</a></li>'
        else:
            self.query_params['page'] = self.current_page + 1
            nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),)
        page_list.append(nex)

        if self.all_count:
            tpl = "<li class='disabled'><a>共%s条数据,页码%s/%s页</a></li>" % (
                self.all_count, self.current_page, self.pager_count,)
            page_list.append(tpl)
        page_str = "".join(page_list)
        return page_str
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kobe_OKOK_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值