• 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

     

  • 相关阅读:
    C# 设计模式-抽象工厂模式
    C# 设计模式-工厂方法模式
    C# 设计模式-简单工厂模式
    C# 设计原则-迪米特法则(最少知识原则)
    C# 设计原则-接口隔离原则
    阻止右击事件并更改为自定义导航栏;
    今日头条滚动新闻版块特效
    抓包工具
    查看页面加载速度
    插件那点事
  • 原文地址:https://www.cnblogs.com/banshaohuan/p/9485863.html
Copyright © 2020-2023  润新知