• Django之分页


    1. Django的内置分页

    1.1 views.py

    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    L = []
    for i in range(999):
        L.append(i)
    
    def index(request):
        current_page = request.GET.get('p')
    
        paginator = Paginator(L, 10)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)
            # has_next              是否有下一页
            # next_page_number      下一页页码
            # has_previous          是否有上一页
            # previous_page_number  上一页页码
            # object_list           分页之后的数据列表
            # number                当前页
            # paginator             paginator对象
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)
        return render(request, 'index.html', {'posts': posts})

    1.2 index.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <ul>
        {% for item in posts %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    
    <div class="pagination">
          <span class="step-links">
            {% if posts.has_previous %}
                <a href="?p={{ posts.previous_page_number }}">Previous</a>
            {% endif %}
              <span class="current">
                Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
              </span>
              {% if posts.has_next %}
                  <a href="?p={{ posts.next_page_number }}">Next</a>
              {% endif %}
          </span>
    </div>
    </body>
    </html>

    2. 扩展Django内置分页

    2.1 views.py

    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    class CustomPaginator(Paginator):
        def __init__(self, current_page, max_pager_num, *args, **kwargs):
            self.current_page = int(current_page)
            self.max_pager_num = max_pager_num
            super(CustomPaginator, self).__init__(*args, **kwargs)
    
        def page_num_range(self):
            # 当前页面
            # self.current_page
            # 总页数
            # self.num_pages
            # 最多显示的页码个数
            # self.max_pager_num
            print(1)
            if self.num_pages < self.max_pager_num:
                return range(1, self.num_pages + 1)
            print(2)
            part = int(self.max_pager_num / 2)
            if self.current_page - part < 1:
                return range(1, self.max_pager_num + 1)
            print(3)
            if self.current_page + part > self.num_pages:
                return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1)
            print(4)
            return range(self.current_page - part, self.current_page + part + 1)
    
    L = []
    for i in range(999):
        L.append(i)
    
    def index(request):
        current_page = request.GET.get('p')
        paginator = CustomPaginator(current_page, 11, L, 10)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)
            # has_next              是否有下一页
            # next_page_number      下一页页码
            # has_previous          是否有上一页
            # previous_page_number  上一页页码
            # object_list           分页之后的数据列表
            # number                当前页
            # paginator             paginator对象
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)
        return render(request, 'index.html', {'posts': posts})

    2.2 index.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <ul>
        {% for item in posts %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    <div class="pagination">
    <span class="step-links">
        {% if posts.has_previous %}
            <a href="?p={{ posts.previous_page_number }}">Previous</a>
        {% endif %}
    
        {% for i in posts.paginator.page_num_range %}
            <a href="?p={{ i }}">{{ i }}</a>
        {% endfor %}
    
        {% if posts.has_next %}
            <a href="?p={{ posts.next_page_number }}">Next</a>
        {% endif %}
    </span>
    </div>
    </body>
    </html>

    3. 自定义分页

    3.1 自定义分页插件

    pager.py

    class Paginator(object):
        def __init__(self, totalCount, currentPage, perPageItemNum=10, maxPageNum=11):
            """
            totalCount:数据总个数
            currentPage:当前页
            perPageItemNum: 每页显示的行数
            maxPageNum:最多显示的页码个数
            """
            self.total_count = totalCount
            try:
                v = int(currentPage)
                if v <= 0:
                    v = 1
                self.current_page = v
            except Exception as e:
                self.current_page = 1
            self.per_page_item_num = perPageItemNum
            self.max_page_num = maxPageNum
    
        @property
        def start(self):
            """数据切片的起始位置"""
            return (self.current_page-1) * self.per_page_item_num
    
        @property
        def end(self):
            """数据切片的结束位置"""
            return self.current_page * self.per_page_item_num
    
        @property
        def num_pages(self):
            """总的页数"""
            a, b = divmod(self.total_count, self.per_page_item_num)
            if b == 0:
                return a
            return a + 1
    
        def page_num_range(self):
            """页码范围"""
            part = int(self.max_page_num / 2)
            # 总的页数少于默认要显示的页码数
            if self.num_pages < self.max_page_num:
                return range(1, self.num_pages + 1)
            # 当前页码处于第一页的前一半位置
            if self.current_page - part < 1:
                return range(1, self.max_page_num + 1)
            # 当前页码处于最后一页的后一半位置
            if self.current_page + part > self.num_pages:
                return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1)
            return range(self.current_page - part, self.current_page + part + 1)
    
        def page_str(self):
            """生成所有的页码"""
            # 创建一个保存所有页码的容器
            page_list = []
    
            # 生成首页和上一页的页码
            first = "<li><a href='?p=1'>首页</a></li>"
            page_list.append(first)
            if self.current_page == 1:
                the_prev = "<li><a href='#'>上一页</a></li>"
            else:
                the_prev = "<li><a href='?p=%s'>上一页</a></li>" % (self.current_page - 1, )
            page_list.append(the_prev)
    
            # 生成中间所有页的页码
            for i in self.page_num_range():
                if i == self.current_page:
                    temp = "<li class='active'><a href='?p=%s'>%s</a></li>" % (i, i, )
                else:
                    temp = "<li><a href='?p=%s'>%s</a></li>" % (i, i, )
                page_list.append(temp)
    
            # 生成下一页和尾页的页码
            if self.current_page == self.num_pages:
                the_next = "<li><a href='#'>下一页</a></li>"
            else:
                the_next = "<li><a href='?p=%s'>下一页</a></li>" % (self.current_page + 1, )
            page_list.append(the_next)
            last = "<li><a href='?p=%s'>尾页</a></li>" % (self.num_pages, )
            page_list.append(last)
    
            # 列表容器中的各个页码转换为字符串
            result = ''.join(page_list)
            return result

    3.2 在后台函数中调用自定义分页插件

    views.py

    user_list = []
    for i in range(1, 999):
        temp = {'username': 'root' + str(i), 'age': i, }
        user_list.append(temp)
        
    def index(request):
        # 获取当前页码号
        current_page = int(request.GET.get('p'))
        # 导入自定义分页插件
        from app01.pager import Paginator
        # 参数依次为: 数据总个数, 当前页码号, 每页显示的行数, 最多显示的页码个数
        # 后两个参数默认为: 10, 11
        obj = Paginator(999, current_page,)
        # obj对象中可调用的属性(方法):
        #     start       当前页的起始条目索引
        #     end         当前页的结束条目索引
        #     page_str()  生成的所有页码结构和样式
        data_list = user_list[obj.start:obj.end]
        return render(request, 'index.html', {'data': data_list, 'page_obj': obj, })

    3.3 模板文件index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
    </head>
    <body>
            {# 数据内容 #}
            <ul>
                {% for row in data %}
                    <li>{{ row.username }} -- {{ row.age }}</li>
                {% endfor %}
            </ul>
    
            {# 分页的内容 #}
            <ul class="pagination">
                {{ page_obj.page_str|safe }}
            </ul>
    </body>
    </html>
  • 相关阅读:
    算法探究-2.retinaNet(Focal Loss)
    C++基础-枚举体 enum class
    C++基础-TypeTraits(进行类型的属性判断) 1.is_lvalue_reference(左值引用判断) 2.is_integral(整形判断) 3.is_class(基本类型判段) 4.is_same(判断类型一致) 5.enable_if(条件判断)
    C++基础-auto(自动分配属性)和decltype(指定分配属性)
    C++基础-正则实战(日期拆分regex_match ,符号拆分sregex_token_iterator, 邮箱的查找 regex_search)
    C++基础-正则表达式 regex_match(匹配) regex_search(查找) regex_replace(替换)
    Shell 入门(三):sed,awk,grep
    Shell 入门(二):数组与函数
    Shell 入门(一):变量和流程控制
    ArcSDE 版本差异提取
  • 原文地址:https://www.cnblogs.com/hgzero/p/13387461.html
Copyright © 2020-2023  润新知