0
点赞
收藏
分享

微信扫一扫

Django自定义分页器

Greatiga 2022-02-05 阅读 52

使用的时候只需要调用该分页器类实例化对象,传入下面两个参数即可

1.请求
2.分页数据即可

"""
自定义的分页组件
使用方法:
    views中
        def number_list(request):
            if request.method == 'GET':
                # 根据条件筛选需要的数据
                numbers = PrettyNumber.objects.all().order_by('-level')

                # 调用分页器类进行自动分页 生成分页器对象 调用html方法 渲染页面即可
                page_obj = Pagination(request, numbers)
                page_string = page_obj.html()
                return render(request, 'number_list.html', locals())
    html中
        <!--数据的展示-->
        {% for i in page_obj.page_queryset %}
            <tr>
                <td> {{ i.id }}</td>
                <td> {{ i.mobile }}</td>
                <td> {{ i.price }}</td>
                <td>{{ i.get_level_display }}</td>
                <td>{{ i.get_status_display }}</td>
                <td>
                    <a class="btn btn-primary btn-xs" href="/number/edit/{{ i.id }}">编辑</a>
                    <a class="btn btn-danger btn-xs" href="/number/delete/?nid={{ i.id }}">删除</a>
                </td>
            </tr>
        {% endfor %}

        <!--分页-->
        <nav aria-label="...">
            <ul class="pagination">
                {{ page_string }}
            </ul>
        </nav>

"""
from django.utils.safestring import mark_safe


class Pagination(object):
    def __init__(self, request, queryset, page_size=10, page_params='page', plus=5):
        """
        request:请求
        queryset:需要分页符合条件的数据
        page_size:每页数据个数 默认为10
        page_params:查询字符串的名称 默认为page
        plus:每页前面显示几页 后面显示几页
        """
        page = request.GET.get(page_params, 1)

        from django.http.request import QueryDict
        import copy
        query_dic = copy.deepcopy(request.GET)              # 默认request.GET不能修改,深拷贝一份就可以修改
        query_dic._mutable = True                           # 还需要该改下 拷贝出来的._mutable属性
        self.page_params = page_params                      # 设置 page_params 分页查询字符串的key
        self.query_dic = query_dic                          # 设置 query_dic拷贝出来的复件 为 属性
        # query_dic.setlist('page', [1111])
        # print(request.GET.urlencode())

        # 如果是一个十进制规范数字 当前页码为规范数字
        try:
            page.isdigit()
            page = int(page)
            print(page, type(page))
        # 不是 规范输入 设置当前页码为1
        except:
            page = 1
        self.page = page                                    # 当前页面
        self.page_size = page_size                          # 每页多少条数据
        self.start = (page - 1) * page_size                 # 从第几条数据开始切片
        self.end = page * page_size                         # 切片到第几条数据
        self.page_queryset = queryset[self.start:self.end]  # 每页数据的内容

        # 总的数据数量
        self.total_count = queryset.count()
        total_page_count, div = divmod(self.total_count, self.page_size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count            # 总页码页码数量
        self.plus = plus                                    # 展示前几条 后几条数据

    def html(self):
        # 定义一个page_str_list用来装载html数据
        page_str_list = []

        # 数据库数据比较少 没有达到11页 即 2*plus + 1页  显示的内容设置为固定显示
        if self.total_page_count <= 2 * self.plus + 1:
            start_page = 1
            end_page = self.total_page_count
        # 数据库的数据比较多,达到11页,考虑小时候的极值,和大时候的极值判断 设置对应的显示内容为固定显示开始或者结束
        else:
            # 小的时候的极值 设置起始页面为1 结束页面动态选择
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus + 1
            # 当前页 > 5 (plus)
            else:
                # 判断大的时候的极值 当前页+plus>最大页面数的时候出问题 设置起始页面为最大页面数-2*plus 结束页码为最大页码数
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2 * self.plus
                    end_page = self.total_page_count
                # 否则中间正常显示即可
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus

        # ?后面的查询字符串
        self.query_dic.setlist(self.page_params, [1])

        # 首页 html标签                                                     注意不能添加查询字符串前面的url,否则其他的就不能使用
        home_page = '<li class="page-item"><a class="page-link disabled" href="?{}">HomePage</a></li>'.format(self.query_dic.urlencode())
        page_str_list.append(home_page)

        # 上一页 html标签
        if self.page <= 1:
            self.query_dic.setlist(self.page_params, [1])
            prev = '<li class="page-item"><a class="page-link disabled" href="?{}">Previous</a></li>'.format(self.query_dic.urlencode())
        else:
            self.query_dic.setlist(self.page_params, [self.page-1])
            prev = '<li class="page-item"><a class="page-link" href="?{}">Previous</a></li>'.format(self.query_dic.urlencode())
        page_str_list.append(prev)

        # 中间页码 html标签
        for i in range(start_page, end_page + 1):               # for range前取后不取,所以需要给结束页码+1
            self.query_dic.setlist(self.page_params, [i])
            if i == self.page:
                # active 为深蓝色选中状态
                ele = '<li class="page-item active"  aria-current="page" ><a class="page-link" href="?{}">{}</a></li>'.format(self.query_dic.urlencode(), i)
            else:
                # 需要标记该字符串为安全的 导入marksafe 后面为字符串的格式化
                ele = '<li class="page-item"><a class="page-link" href="?{}">{}</a></li>'.format(self.query_dic.urlencode(), i)
            page_str_list.append(ele)

        # 下一页 html标签
        if self.page >= self.total_page_count:
            self.query_dic.setlist(self.page_params, [self.total_page_count])
            Next = '<li class="page-item"><a class="page-link" href="?{}">Next</a></li>'.format(self.query_dic.urlencode())
        else:
            self.query_dic.setlist(self.page_params, [self.page + 1])
            Next = '<li class="page-item"><a class="page-link" href="?{}">Next</a></li>'.format(self.query_dic.urlencode())
        page_str_list.append(Next)

        # 尾页 html标签
        self.query_dic.setlist(self.page_params, [self.total_page_count])
        trailer_page = '<li class="page-item"><a class="page-link disabled" href="?{}">TrailerPage</a></li>'.format(self.query_dic.urlencode())
        page_str_list.append(trailer_page)

        # 搜索 html标签
        search_string = """
                        <li>
                            <!-- 页面跳转 -->
                            <form method="get" style="float:left; margin-left: -1px" >
                                <div class="input-group" style="width: 200px">
                                    <input type="text" name="page"
                                           style="position: relative; float: left; display: inline-block; width: 00px; border-radius: 0"
                                           class="form-control" placeholder="页码">
                                    <span class="input-group-btn">
                                        <button class="btn btn-default" type="submit">Jump</button>
                                    </span>
                                </div>
                            </form>
                        </li>
                        """
        page_str_list.append(search_string)

        # 将page_string传递给后端
        page_string = mark_safe("".join(page_str_list))
        return page_string
举报

相关推荐

0 条评论