自定义分页

当数据库中数据有很多,我们通常会在前端页面做分页展示。

分页的数据可以在前端页面实现,也可以在后端实现分页;后端实现分页的原理就是每次只请求一页数据。

装备数据:

批量导入测试数据,在django项目的根目录下新建一个py文件,将下面代码copy进去

import os
from app_bms import models

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
    import django
    django.setup()
    
    obj = [models.User(name="佩奇{}号".format(i), age=i) for i in range(1, 1001)]
    models.User.objects.bulk_create(obj, 100)

自定义分页:

在django根目录下新建一个 Python Package 文件,再新建一个py文件保存封装好的一个用于分页的类。

比如:

class Pagination(object):
    """
    一个用于分页的类
    """
    def __init__(self, current_page, total_count, url_prefix, per_page_num=10, max_page=11):
        """
        :param current_page: 当前页码数
        :param total_count: 总的数据
        :param url_prefix: a标签href的前缀
        :param per_page_num: 默认每页显示10条数据
        :param max_page: 默认每个页面最多显示11个页码
        """
        self.url_prefix = url_prefix
        self.max_page = max_page

        # 总页数,余页 = 总数据/每页显示数据
        total_page, remainder = divmod(total_count, per_page_num)
        if not total_page:
            total_page = 1
        if remainder:
            total_page += 1
        self.total_page = total_page

        try:
            current_page = int(current_page)
            # 如果输入的页码数超过了最大的页码数,默认返回最后一页
            if current_page > total_page:
                current_page = total_page
        except Exception:
            # 当输入的页码不是数字的时候,默认返回第一页
            current_page = 1
        self.current_page = current_page

        # 定义两个变量保存数据从哪儿取到哪儿
        self.data_start = (current_page-1)*per_page_num
        self.data_end = current_page*per_page_num

        # 页面总共展示多少条页码
        if total_page < self.max_page:
            self.max_page = total_page
        half_max_page = self.max_page // 2

        # 页面上展示的页码从哪开始
        page_start = current_page - half_max_page
        # 页面上展示的页码到哪结束
        page_end = current_page + half_max_page
        if page_start <= 1:
            page_start = 1
            page_end = self.max_page
        if page_end >= total_page:
            page_end = total_page
            page_start = total_page - self.max_page + 1
        self.page_start = page_start
        self.page_end = page_end

    @property
    def start_data(self):
        return self.data_start

    @property
    def end_data(self):
        return self.data_end

    def page_html(self):
        # 自己拼接分页的html代码
        html_str_list = []
        # 首页
        html_str_list.append('<li><a href="{}?page=1">首页</a></li>'.format(self.url_prefix))
        # 判断 如果是第一页,就没有上一页
        if self.current_page <= 1:
            html_str_list.append('<li class="disabled"><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.current_page - 1))
        else:
            html_str_list.append('<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.url_prefix, self.current_page - 1))
        # 中间显示的页数
        for i in range(self.page_start, self.page_end+1):
            # 如果是当前页就加一个active样式类
            if i == self.current_page:
                tmp = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
            else:
                tmp = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
            html_str_list.append(tmp)
        # 判断 如果是最后一页,就没有下一页
        if self.current_page >= self.total_page:
            html_str_list.append('<li class="disabled"><a href="#"><span aria-hidden="true">&raquo;</span></a></li>')
        else:
            html_str_list.append('<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(self.url_prefix, self.current_page + 1))
        # 尾页
        html_str_list.append('<li><a href="{}?page={}">尾页</a></li>'.format(self.url_prefix, self.total_page))
        page_html = "".join(html_str_list)
        return page_html
自定义分页

如何使用在相应处修改即可

# view.py

from utils.mypage import Pagination

def show_user(request):
    # 从URL取参数
    current_page = request.GET.get("page")
    # 总数据是多少
    total_count = models.User.objects.all().count()
    page_obj = Pagination(current_page, total_count, url_prefix="/show_user/",  per_page_num=10, max_page=7)
    users = models.User.objects.all()[page_obj.start_data:page_obj.end_data]
    page_html = page_obj.page_html()
    return render(request, "show_user.html", {"users": users, "page_html": page_html})

html 部分 html 代码的分页部分都相同(封装好的类返回来的 html 代码有 li 标签,html 部分不必再写)

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>show_user</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3 col-sm-6 col-sm-offset-3">

            <div class="table-responsive">{# 表格开始 #}
                <table class="table table-bordered">
                    <thead>
                    <tr>
                        <th>number</th>
                        <th>name</th>
                        <th>age</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for user in users %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.age }}</td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>{# 表格结束 #}

            <div class="pull-right">{# 分页开始 #}
                <nav aria-label="Page navigation">
                    <ul class="pagination">
                        {{ page_html|safe }}
                    </ul>
                </nav>
            </div>{# 分页结束 #}

        </div>
    </div>
</div>
</body>
</html>

 PS:

封装的类和html页面都使用了Bootstrap样式,如不需要,稍加修改即可。

 

posted @ 2018-11-04 10:12  就俗人一个  阅读(507)  评论(0编辑  收藏  举报