• Django自定制分页器Pagination


    自定制分页器组件(Pagination)

    1、封装分页器

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    
    class Pagination(object):
        def __init__(self, request, data_set, per_page_data=10, nav_bar_num=11):
    
            """
            自定制分页器组件:
                            供调用属性:data、nav_bar
                            假设接收分页器处理后结果的对象为show_page
                            show_page.data:     在当前页面上显示的数据集
                            show_page.nav_bar:  页码导航条 html生成代码
    
            :param request:     一般来说是 request.GET 请求
            :param data_set:        需要进行分页处理的数据对象,即总数据
            :param per_page_data:    分页后每个页面所显示的数据条数,默认10条
            :param nav_bar_num:    页码导航条上最多显示的页码数量
            """
            self.base_url = request.path_info
            self.query_params = request.GET.copy()  # 保留原url上其他参数
            # self.query_params._mutable = True
            self.per_page_data = per_page_data
            self.nav_bar_num = nav_bar_num
    
            # 列表、QuerySet等数据集
            # 总数据量
            try:
                total_data = data_set.count()
            except TypeError:
                total_data = len(data_set)
            self.total_data = total_data
    
            # 总页数
            self.total_page, more = divmod(self.total_data, self.per_page_data)
            if more or not total_data:
                self.total_page += 1
            # quotient, more = divmod(total_data, self.per_page_count)
            # self.total_page = quotient + 1 if more or not total_data else quotient
    
            # 当前页id
            current_page_id = request.GET.get('page')
            try:
                current_page_id = int(current_page_id)
            except (ValueError, TypeError):
                current_page_id = 1
            self.current_page_id = current_page_id
    
            # 控制“.../?page=99999...”page参数乱入负数、太大数等情况(两个if,顺序不能反)
            if self.current_page_id > self.total_page:
                self.current_page_id = self.total_page
            if self.current_page_id < 1:
                self.current_page_id = 1
    
            # 切片取出需要渲染在当前页面上的数据集
            data_start = (self.current_page_id - 1) * self.per_page_data
            data_end = self.current_page_id * self.per_page_data
    
            self.data = data_set[data_start: data_end]
    
        # 方法变属性
        @property
        def nav_bar(self):
    
            # 页码导航条最左边的页码id
            left_page_id = self.current_page_id - self.nav_bar_num // 2
    
            # 页码导航条最右边的页码id
            right_page_id = self.current_page_id + self.nav_bar_num // 2
    
            # 两端控制溢出
            if left_page_id < 1:
                left_page_id, right_page_id = 1, self.nav_bar_num
            if right_page_id > self.total_page:
                left_page_id, right_page_id = self.total_page - self.nav_bar_num + 1, self.total_page
    
            # 数据量不足的情况下,控制页码导航条的显示
            if self.total_page < self.nav_bar_num:
                left_page_id, right_page_id = 1, self.total_page
    
            prev_page_id = self.current_page_id - 1 if self.current_page_id != 1 else self.current_page_id
            next_page_id = self.current_page_id + 1 if self.current_page_id != self.total_page else self.current_page_id
    
            # 页码导航条部分的html标签代码
            nav_bar_list = ['<nav aria-label="Page navigation"><ul class="pagination">', ]
    
            # 只更改url中原参数集中的page参数,其他参数还要编制在url上
            self.query_params['page'] = 1
            nav_bar_list.append('<li><a href="{}?{}">首页</a></li>'.format(self.base_url, self.query_params.urlencode()))
            self.query_params['page'] = prev_page_id
            nav_bar_list.append('<li><a href="{}?{}">&laquo;</a></li>'.format(self.base_url, self.query_params.urlencode()))
    
            for i in range(left_page_id, right_page_id + 1):
                self.query_params['page'] = i
                if i == self.current_page_id:
                    tpl = '<li class="active"><a href="{}?{}">{}</a></li>'
                else:
                    tpl = '<li><a href="{}?{}">{}</a></li>'
                nav_bar_list.append(tpl.format(self.base_url, self.query_params.urlencode(), i))
    
            self.query_params['page'] = next_page_id
            nav_bar_list.append('<li><a href="{}?{}">&raquo;</a></li>'.format(self.base_url, self.query_params.urlencode()))
            self.query_params['page'] = self.total_page
            nav_bar_list.append('<li><a href="{}?{}">尾页</a></li>'.format(self.base_url, self.query_params.urlencode()))
            tpl = '<li><a class="disabled" style="color:#333;">共{}条数据,页码{}/{}页</a></li>'
            nav_bar_list.append(tpl.format(self.total_data, self.current_page_id, self.total_page))
    
            nav_bar_list.append('</ul></nav>')
    
            nav_bar_html = ''.join(nav_bar_list)
    
            return nav_bar_html
    自定制分页器

    2、在视图函数中调用

    from utils.pagination import Pagination
        
    def show_books(request):
        book_list = models.Books.objects.all()
        # book_list = models.Books.objects.all().value_list('title', 'authors')
        show_obj = Pagination(request, book_list)
        return render(request, 'books.html', {'show_obj': show_obj})
    视图中调用

    3、在模板html中调用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/css/bootstrap/bootstrap3.3.7-min.css">
    </head>
    <body>
    
    <div class="container">
        <table class="table table-bordered">
            <thead>
            <tr>
                <td>序号</td>
                <td>ID</td>
                <td>书名</td>
            </tr>
            </thead>
            <tbody>
            {% for book in show_obj.data %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ book.id }}</td>
                    <td>{{ book.title }}</td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
        {{ show_obj.nav_bar|safe }}
    </div>
    
    </body>
    </html>
    模板中调用

    ok

  • 相关阅读:
    MIKROTIK ROS+PHP+MYSQL实现从数据库中配置DNS服务器
    随手记
    05 通过python开启静态http服务
    名称空间和作用域
    cs常用功能
    初识Cobalt Strike
    msf之手机木马生成&利用
    msf之meterpreter命令
    BURPSUITE的常用模块
    BURPSUITE专业汉化版安装
  • 原文地址:https://www.cnblogs.com/kingon/p/9452240.html
Copyright © 2020-2023  润新知