zoukankan      html  css  js  c++  java
  • Web框架django进阶篇

    分页

    一、Django内置分页

    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('page')  # 通过get请求得到当前请求的页数
    
        paginator = Paginator(L, 10)            # 实例化传入俩个参数(所有数据,当页显示条数)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)# 传入当前页码,观源码可得实例化了一个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})  # posts封装了一些方法
    Views.py
    <!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 }}">上一页</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 }}">下一页</a>
              {% endif %}
          </span>
    
    </div>
    </body>
    </html>
    HTML

    那么、Django的内置分页基本俩个类实现、并封装了一些方法来使用、此时并不能满足有一些的需求

    二、Django内置分页的拓展

    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    user = []
    for i in range(1, 1001):
        dic = {'name': 'root' + str(i), 'pwd': i}
        user.append(dic)
    
    
    class DiyPaginator(Paginator):
        def __init__(self, current_page,max_pager_num, *args, **kwargs):
            """
            :param current_page:  当前页码
            :param max_pager_num: 显示页码个数的最大值
            :param args:
            :param kwargs:
            """
            self.current_page = int(current_page)
            self.max_pager_num = int(max_pager_num)
            super(DiyPaginator,self).__init__(*args,**kwargs)
    
        def pager_num_range(self):
            # 需要的参数
            # 当前页码    self.current_page
            # 页码数量    self.max_pager_num
            # 总页数      self.num_pages
    
            # 如果总页数小于页码个数最大值的情况
            if self.num_pages < self.max_pager_num:
                return range(1,self.num_pages+1)     # 返回 从 1 到 总页数
    
            # 如果总页数大于页码数量且当前所选页码小于页码数量的一半    
            part = self.max_pager_num//2
            if self.current_page <= part:
                return range(1,self.max_pager_num+1) # 返回 从 1 到 页码个数最大值
    
            # 如果当前页码加一半的页码 大于 总页数
            if (self.current_page+part) > self.num_pages:
                # 返回 从总页数-最大页码数 到 总页数      range的用法在此不作解释
                # 例如 96页+5页 超出总页数 则返回的范围是 从 总页数-最大页码数量+1 到 总页数+1    
                return range(self.num_pages-self.max_pager_num+1,self.num_pages+1)
    
            # 其余情况从 当前页码减去显示页码的平均值开始  到 当前页码加显示页码的平均值(并加一)结束
            return range(self.current_page-part,self.current_page+part+1)
    
    
    def index(request):
        p = request.GET.get('page')
        start = (int(p)-1)*10
        end = int(p)*10
        data = user[start:end]
        return render(request,'index.html',{'data':data,'user':user})
    
    
    def index1(request):
        current_page = request.GET.get('page')
        paginator = DiyPaginator(current_page, 9, user, 10)
        # Paginator所封装的方法
        # 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,'index1.html',{'posts':posts})
    扩展内置分页:views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <ul>
            {% for row in posts.object_list %}
                <li>{{ row.name }}-{{ row.pwd }}</li>
            {% endfor %}
        </ul>
        {% include 'include/pager.html' %}
    </body>
    </html>
    
    ##################################
    include 组件代码
    
    {% if posts.has_previous %}
        <a href="/index1?page={{ posts.previous_page_number }}">上一页</a>
    {% endif %}
    
    {% for num in posts.paginator.pager_num_range %}
        {% if num == posts.number %}
            <a style="color: red;font-size: 20px" href="/index1?page={{ num }}">{{ num }}</a>
        {% else %}
            <a href="/index1?page={{ num }}">{{ num }}</a>
        {% endif %}
    {% endfor %}
    
    {% if posts.has_next %}
        <a href="/index1?page={{ posts.next_page_number }}">下一页</a>
    {% endif %}
    <span>
        当前页:{{ posts.number }}&nbsp;&nbsp;总页数:{{ posts.paginator.num_pages }}
    </span>
    扩展内置分页:HTML

    三、自定义分页

    • 创建处理分页数据的类
    • 根据分页数据获取数据
    • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]或者额外的作出一些拓展也可以

    创建处理分页数据的类时,大致也需要四个参数(详情观看类构造方法)

      1、为了减少服务器内存的负载,不再获取所有数据的,而是获得所有数据的总个数,然后再根据索引查数据库的内容

      2、当前页码

      3、每页显示的行数

      4、页码显示的数量

    对于页数的显示大致也可以归类为三种情况(详情观看类中page_num_range函数)

      1、计算的总页数小于页码显示的数量

      2、计算的总页数大于页码显示的数量

        A、当前页数小于页码数量的一半

        B、当前页数加页码数量的一半超出总页数的范围

      3、正常情况

        从 当前页数 减 一半页码数量 到 当前页数 加 一半页码数量

    class Pagination(object):
        def __init__(self,totalCount,currentPage,perPageItemNum=10,maxPageNum=9):
            """
            :param totalCount:     所有数据总个数
            :param currentPage:    当前页数
            :param perPageItemNum: 每页显示行数
            :param maxPageNum:     最多显示页码个数
            """
            self.total_count = totalCount
            # 对当前的页码进行一次异常捕获
            try:
                currentPage = int(currentPage)
                if currentPage <= 0:
                    currentPage = 1
                self.current_page = currentPage
            except Exception:
                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):
            """
            总页数
            :return:
            """
            # 得商取余得内置函数
            x, o = divmod(self.total_count,self.per_page_item_num)
            if o == 0:
                return x
            return x + 1
    
        @property
        def page_num_range(self):
            if self.num_pages < self.max_page_num:
                return range(1, self.num_pages+1)
    
            part = self.max_page_num//2
            if self.current_page <= part:
                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='/index2/?page=1'>首页</a></li>"
            page_list.append(first)
    
            if self.current_page == 1:
                prev_page = "<li><a href='#'>上一页</a></li>"
            else:
                prev_page = "<li><a href='/index2/?page=%s'>上一页</a></li>" %(self.current_page-1)
            page_list.append(prev_page)
    
            for i in self.page_num_range:
                if i == self.current_page:
                    temp = "<li class='active'><a href='/index2/?page=%s'>%s</a></li>" %(i,i)
                else:
                    temp = "<li><a href='/index2/?page=%s'>%s</a></li>" % (i, i)
                page_list.append(temp)
    
            if self.current_page == self.num_pages:
                next_page = "<li><a href='#'>下一页</a></li>"
            else:
                next_page = "<li><a href='/index2/?page=%s'>下一页</a></li>" %(self.current_page+1)
            page_list.append(next_page)
    
            last = "<li><a href='/index2/?page=%s'>尾页</a></li>" %self.num_pages
            page_list.append(last)
    
            return ''.join(page_list)
    自定义分页
    def index2(request):
        from page.diypage import Pagination
        current_page = request.GET.get('page')
        page_obj = Pagination(1000,current_page)
    
        data_list = user[page_obj.start:page_obj.end]
        return render(request,'index2.html',{
            'data' : data_list,
            'page_obj' : page_obj
        })
    自定义分页:views.py
    # 本页面引用了bootstrap样式
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css" />
    </head>
    <body>
        <ul>
            {% for row in data %}
                <li>{{ row.name }}-{{ row.pwd }}</li>
            {% endfor %}
        </ul>
        {% for i in page_obj.pager_num_range %}
            <a href="/index2/?page={{ i }}">{{ i }}</a>
        {% endfor %}
        <hr/>
    
        <ul class="pagination pagination-sm">
            {{ page_obj.page_str|safe }}
          </ul>
        <div style="height: 300px;"></div>
    </body>
    </html>
    自定义分页:HTML
  • 相关阅读:
    POJ 1611 The Suspects
    POJ 2001 Shortest Prefixes(字典树)
    HDU 1251 统计难题(字典树 裸题 链表做法)
    G++ C++之区别
    PAT 乙级 1013. 数素数 (20)
    PAT 乙级 1012. 数字分类 (20)
    PAT 乙级 1009. 说反话 (20)
    PAT 乙级 1008. 数组元素循环右移问题 (20)
    HDU 6063 17多校3 RXD and math(暴力打表题)
    HDU 6066 17多校3 RXD's date(超水题)
  • 原文地址:https://www.cnblogs.com/liaoboshi/p/6576142.html
Copyright © 2011-2022 走看看