• Python中的分页管理


    1,自定义分页

    #utils文件夹下的page.py文件
    
    class PagerHelper:
        #total_count总的页数,current_page当前页数,base_url页面用来分页显示的URL如http://127.0.0.1:8000/classes.html/?p=71
        #base_url为/calsses.html per_page每一页有多少条数据
        def __init__(self,total_count,current_page,base_url,per_page=10):
            self.total_count = total_count
            self.current_page = current_page
            self.base_url = base_url
            self.per_page = per_page
    
        @property
        def db_start(self):
            return (self.current_page -1) * self.per_page
    
        @property
        def db_end(self):
            return self.current_page * self.per_page
        #返回总的页数
        def total_page(self):
            v, a = divmod(self.total_count, self.per_page)
            if a != 0:
                v += 1
            return v
        #返回页码的HTML,默认是11页显示,小于11页时1-总页数,
        #当前页小于6页时总显示1-11页,当前页加5(最后一页大于总页数时)显示(总页数-11,总页数)
        def pager_str(self):
    
            v = self.total_page()
    
            pager_list = []
            if self.current_page == 1:
                pager_list.append('<a href="javascript:void(0);">上一页</a>')
            else:
                pager_list.append('<a href="%s?p=%s">上一页</a>' % (self.base_url, self.current_page - 1,))
    
            # 6,1:12
            # 7,2:13
            if v <= 11:
                pager_range_start = 1
                pager_range_end = v
            else:
                if self.current_page < 6:
                    pager_range_start = 1
                    pager_range_end = 11 + 1
                else:
                    pager_range_start = self.current_page - 5
                    pager_range_end = self.current_page + 5 + 1
                    if pager_range_end > v:
                        pager_range_start = v - 10
                        pager_range_end = v + 1
    
            for i in range(pager_range_start, pager_range_end):
                if i == self.current_page:
                    pager_list.append('<a class="active" href="%s?p=%s">%s</a>' % (self.base_url, i, i,))
                else:
                    pager_list.append('<a href="%s?p=%s">%s</a>' % (self.base_url, i, i,))
    
            if self.current_page == v:
                pager_list.append('<a href="javascript:void(0);">下一页</a>')
            else:
                pager_list.append('<a href="%s?p=%s">下一页</a>' % (self.base_url, self.current_page + 1,))
    
            pager = "".join(pager_list)
            return pager
    自定义分页

    在函数中调用

    #获取数据
    total_count = 总的页数
    current_page = 当前页数
     '/classes.html' --> 当前分页的url
    5 每一页显示数据,默认是10
    
    ######
    from utils.page import PagerHelper
            obj = PagerHelper(total_count, current_page, '/classes.html',5)
            pager = obj.pager_str()
    
            cls_list = models.Classes.objects.all()[obj.db_start:obj.db_end]
    
           # current_user = request.session.get('username')
            return render(request,
                          'classes.html',
                          {'username': current_user, 'cls_list': cls_list, 'str_pager': pager})
    在views中使用

     2,使用paginator和bootstrap实现分页

    配置分页的接口

    #在utilsde page.py中配置
    from django.core.paginator import Paginator
    from django.conf import settings
    
    #接受两个参数
    #request
    #blogs_all_list所有的博客,Blog.objects.all()
    def page_paginator(request,blogs_all_list):
        paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        page_num = request.GET.get('page', 1)  # 获取url的页面参数(GET请求)
        page_of_blogs = paginator.get_page(page_num)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
        currentr_page_num = page_of_blogs.number  # 获取当前页码
        # 获取当前页码前后各2页的页码范围
        page_range = list(range(max(currentr_page_num - 2, 1), currentr_page_num)) + 
                     list(range(currentr_page_num, min(currentr_page_num + 2, paginator.num_pages) + 1))
        # 加上省略页码标记
        if page_range[0] - 1 >= 2:
            page_range.insert(0, '...')
        if paginator.num_pages - page_range[-1] >= 2:
            page_range.append('...')
        # 加上首页和尾页
        if page_range[0] != 1:
            page_range.insert(0, 1)
        if page_range[-1] != paginator.num_pages:
            page_range.append(paginator.num_pages)
        # 返回当前页的博客,和[首页,前2页,.....当前页,....,后两页,尾页]
        return page_of_blogs,page_range
    View Code

    在views中调用接口

    from utils.page import page_paginator
    
    if request.method == 'GET':
        blogs_all_list = models.Classes.objects.all()
        page_of_blogs,page_range = page_paginator(request,blogs_all_list)
        current_user = request.session.get('username')
        return render(request,'classes.html',              {'username':current_user,'blogs':page_of_blogs.object_list,'page_of_blogs':page_of_blogs,'page_range': page_range})
    View Code

    在模板中使用bootstrap

    #在模板temolates中的layout.html中调用
    {% load staticfiles %}
    
    <link rel="stylesheet" href="{% static 'base.css' %}">
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
        <script type="text/javascript" src="{% static 'jquery-1.12.4.min.js' %}"></script>
        <script type="text/javascript" src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
        <script type="text/javascript" src="{% static 'notifications/notify.js' %}"></script>
    View Code

    在setting中配置每一页显示的数据

    EACH_PAGE_BLOGS_NUMBER = 10

    在前端html中使用

     <div class="paginator">
                        <ul class="pagination">
                            {# 上一页 #}
                            <li>
                                {% if page_of_blogs.has_previous %}
                                    <a href="?p={{ page_of_blogs.previous_page_number }}" aria-label="Previous">
                                        <span aria-hidden="true">&laquo;</span>
                                    </a>
                                {% else %}
                                    <span aria-hidden="true">&laquo;</span>
                                {% endif %}
                            </li>
                            {# 全部页码 #}
                            {% for page_num in page_range %}
                                {% if page_num == page_of_blogs.number %}
                                    <li class="active"><span>{{ page_num }}</span></li>
                                {% else %}
                                    {% if page_num == '...' %}
                                        <li><span>{{ page_num }}</span></li>
                                    {% else %}
                                        <li><a href="?p={{ page_num }}">{{ page_num }}</a></li>
                                    {% endif %}
                                {% endif %}
                            {% endfor %}
                            {# 下一页 #}
                            <li>
                                {% if page_of_blogs.has_next %}
                                    <a href="?p={{ page_of_blogs.next_page_number }}" aria-label="Next">
                                        <span aria-hidden="true">&raquo;</span>
                                    </a>
                                {% else %}
                                    <span aria-hidden="true">&raquo;</span>
                                {% endif %}
                            </li>
                        </ul>
                        <p>
                            共有{{ page_of_blogs.paginator.count }}篇博客,
                            当前第{{ page_of_blogs.number }}页,共{{ page_of_blogs.paginator.num_pages }}页
                        </p>
                    </div>
    View Code

     参考gitee的地址https://gitee.com/wuzhibin112423/python_paging_management.git

    3、使用django的CBV模型实现分页

    views中使用的是CBV,继承了ListView类

    class IndexView(ListView):
        model = Post
        template_name = 'blog/index.html'
        context_object_name = 'post_list'
        # 指定 paginate_by 属性后开启分页功能,其值代表每一页包含多少篇文章
        paginate_by = 10
    
    
    #ListView默认给前端传递了以下的参数以供使用
    #paginator ,即 Paginator 的实例。
    #page_obj ,当前请求页面分页对象。
    #is_paginated,是否已分页。只有当分页后页面超过两页时才算已分页。
    #object_list,请求页面的对象列表,和 post_list 等价。所以在模板中循环文章列表时可以选 post_list ,也可以选 object_list。
    views
    templates/blog/index.html
     
    {% if is_paginated %}
    <div class="pagination-simple">
      <!-- 如果当前页还有上一页,显示一个上一页的按钮 -->
      {% if page_obj.has_previous %}
        <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
      {% endif %}
      <!-- 显示当前页面信息 -->
      <span class="current">第 {{ page_obj.number }} 页 / 共 {{ paginator.num_pages }} 页</span>
      <!-- 如果当前页还有下一页,显示一个下一页的按钮 -->
      {% if page_obj.has_next %}
        <a href="?page={{ page_obj.next_page_number }}">下一页</a>
      {% endif %}
    </div>
    {% endif %}
    HTML

     4、使用第三方的包:django-pure-pagination来实现分页

    1、先安装应用

    pip install django-pure-pagination

    2,注册APP

    INSTALLED_APPS = [
        # ...
        'pure_pagination',  # 分页
     
        'blog.apps.BlogConfig',  # 注册 blog 应用
        'comments.apps.CommentsConfig',  # 注册 comments 应用
    ]
    注册app

    3.修改views

    from pure_pagination import PaginationMixin
    
    class IndexView(PaginationMixin, ListView):
        model = Post
        template_name = 'blog/index.html'
        context_object_name = 'post_list'
        paginate_by = 10
    views

    4、在settings配置分页

    # django-pure-pagination 分页设置
    
    PAGINATION_SETTINGS = {
    
        'PAGE_RANGE_DISPLAYED': 4, # 分页条当前页前后应该显示的总页数(两边均匀分布,因此要设置为偶数),
    
        'MARGIN_PAGES_DISPLAYED': 2, # 分页条开头和结尾显示的页数
    
        'SHOW_FIRST_PAGE_WHEN_INVALID': True, # 当请求了不存在页,显示第一页
    
    }
    settings

    5、在模板中使用

    {% if is_paginated %}
    
        {{ page_obj.render }}
    
    {% endif %}
    HTML

    6、使用自定义模板覆盖预定义的模板

    预定义的模板太丑,所以需要设置自定义的模板覆盖预定义的模板,django查找模板的顺序是首先在项目配置的模板根路径寻找,没有找到的话,

    再去应用的templates目录下寻找。分页模板预定义的路径为 pure_pagination/pagination.html,所以我们可以在项目模板根路径下建立一个一模

    一样的文件结构就可以覆盖。

    /templates/pure_pagination/pagination.html
    
    <div class="text-center pagination" style=" 100%">
      <ul>
        {% if page_obj.has_previous %}
          <li><a href="?{{ page_obj.previous_page_number.querystring }}"
                 class="prev">&lsaquo;&lsaquo; </a></li>
        {% else %}
          <li><span class="disabled prev">&lsaquo;&lsaquo; </span></li>
        {% endif %}
        {% for page in page_obj.pages %}
          {% if page %}
            {% ifequal page page_obj.number %}
              <li class="current"><a href="#">{{ page }}</a></li>
            {% else %}
              <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
            {% endifequal %}
          {% else %}
            ...
          {% endif %}
        {% endfor %}
        {% if page_obj.has_next %}
          <li><a href="?{{ page_obj.next_page_number.querystring }}" class="next"> &rsaquo;&rsaquo;</a>
          </li>
        {% else %}
          <li><span class="disabled next"> &rsaquo;&rsaquo;</span></li>
        {% endif %}
      </ul>
    </div>
    pagination.html
    人生苦短,我用cnblog
  • 相关阅读:
    对 Spring IoC 的理解
    初识 Spring 框架
    CSS 全局样式
    Bootstrap 12 栅格系统
    551 闭包,浏览器垃圾回收机制/内存收机制
    550 JavaScript运行机制之“堆栈”
    549 数据类型转换汇总:转换为Number、字符串、布尔,比 较操作==、===,练习题
    547 Promise:Ajax 的串行、并行, Promise的executor和状态,then、catch、finally,then链
    546 变量提升
    545 parseInt解析
  • 原文地址:https://www.cnblogs.com/wuzhibinsuib/p/12824701.html
Copyright © 2020-2023  润新知