Django分页类的封装

Django分页类的封装

封装

之前有提到(Django分页的实现)会多次用到分页,将分页功能封装起来能极大提高效率。

其实不是很难,就是将之前实现的代码全都放到类中,将需要用到的参数,比如,page_num, total_count, url_prefix, per_page, max_page,以参数的形式传到类中进行初始化,而后的实现代码即可用 self.变量名 的形式使用自己分页类内部的变量。

Page 类

class myPage():
    def __init__(self, page_num, total_count, url_prefix, per_page=10, max_page=11):
        """

       :param page_num: 当前页码数
       :param total_count: 数据总数
       :param url_prefix: a标签href的前缀
       :param per_page: 每页显示多少条数据
       :param max_page: 页面上最多显示几个页码
       """
        self.url_prefix = url_prefix
        self.max_page = max_page
        self.per_page = per_page

        total_page, m = divmod(total_count, per_page)
        if m > 0:
            total_page += 1

        self.total_page = total_page

        try:
            page_num = int(page_num)
            # 如果输入页码数过大,默认跳到最后一页
            if page_num > total_page:
                page_num = total_page
        except Exception as e:
            page_num = 1

        self.page_num = page_num

        self.data_start = (page_num - 1) * 10
        self.data_end = page_num * 10

        # 1. 先实现一半一半
        max_page = 11
        # 10. 如果数据量少,页数也少
        if total_page < max_page:
            self.max_page = total_page
        half_max_page = max_page // 2
        page_start = page_num - half_max_page
        page_end = page_num + half_max_page

        # 2. 特殊情况一:页码前面出现负值
        if page_start < 1:
            page_start = 1
            page_end = self.max_page

        # 3. 特殊情况二:页码后面出现空白页
        if page_end >= total_page:
            page_start = total_page - self.max_page + 1
            page_end = total_page

        self.page_start = page_start
        self.page_end = page_end

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

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

    def page_html(self):
        page_html_list = []

        # 9. 解决在首页处点前一页
        if self.page_num == 1:
            page_html_list.append(
                '<li class="disabled"><a href="#"><span aria-hidden="true">&laquo;</span></a></li>')
        else:
            page_html_list.append(
                '<li><a href="{0}?pages={1}"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.url_prefix,
                                                                                                      self.page_num - 1))

        # 4. 加上首页
        page_html_list.append('<li><a href="{}?pages=1">首页</a></li>'.format(self.url_prefix))

        for i in range(self.page_start, self.page_end + 1):
            # 11. 对当前页加上活动active样式类
            if i == self.page_num:
                temp = '<li class="active"><a href="{0}?pages={1}">{1}</a></li>'.format(self.url_prefix, i)
            else:
                temp = '<li><a href="{0}?pages={1}">{1}</a></li>'.format(self.url_prefix, i)
            page_html_list.append(temp)

        # 5. 加上尾页
        page_html_list.append('<li><a href="{0}?pages={1}">尾页</a></li>'.format(self.url_prefix, self.total_page))

        # 8. 解决最后一页时点后一页
        if self.page_num == self.total_page:
            page_html_list.append(
                '<li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>')
        else:
            page_html_list.append(
                '<li><a href="{0}?pages={1}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                    self.url_prefix,
                    self.page_num + 1))

        # 转成字符串
        page_html = "".join(page_html_list)
        return page_html

前端模板代码

前端模板代码没有什么改变

<div class="container">
    <table class="table table-bordered">
        <thead>
        <tr>
            <th>序号</th>
            <th>id</th>
            <th>部门名称</th>
        </tr>
        </thead>
        <tbody>
        {% for dept in depts %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ dept.id }}</td>
                <td>{{ dept.name }}</td>
            </tr>
        {% endfor %}

        </tbody>
    </table>

    <nav aria-label="Page navigation">
        <ul class="pagination">

            {{ page_html|safe }}


        </ul>
    </nav>
</div>

views 中的代码

只需要实例化分页类就能实现分页操作,与之前的方法相比,代码量减少了不少。

def depts(request):
    # 从相应模块中导入分页类
    from utils.myPage import myPage

    all_depts = models.Dept2.objects.all()
    page_num = request.GET.get("pages")
    total_num = models.Dept2.objects.all().count()
    
    # 实例化分页类
    page_obj = myPage(page_num, total_num, '/depts/', per_page=10, max_page=11)
    # 通过实例的变量从数据库中取出需要展示的数据
    ret = models.Dept2.objects.all()[page_obj.start:page_obj.end]
    # 由实例调用函数生成需要的HTML代码
    dept_page_html = page_obj.page_html()
    return render(request, "depts.html", {"depts": ret, "page_html": dept_page_html})

 

效果图

GitHub地址:https://github.com/protea-ban/oldboy/tree/master/s9day71/ormday71

 

原文地址:https://www.cnblogs.com/banshaohuan/p/9485863.html