zoukankan      html  css  js  c++  java
  • 【前端】Django分页器

    一、内置分页器(paginator)

    分页器的使用

    >>> from django.core.paginator import Paginator
    >>> objects = ['john', 'paul', 'george', 'ringo']
    >>> p = Paginator(objects, 2)
     
    >>> p.count        #数据总数
    4
    >>> p.num_pages    #总页数
    2
    >>> type(p.page_range)  # `<type 'rangeiterator'>` in Python 2.
    <class 'range_iterator'>
    >>> p.page_range        #页码的列表
    range(1, 3)     # =========[1,2]
     
    >>> page1 = p.page(1)   #第1页的page对象
    >>> page1
    <Page 1 of 2>
    >>> page1.object_list   #第1页的数据
    ['john', 'paul']
     
    >>> page2 = p.page(2)
    >>> page2.object_list    #第2页的数据
    ['george', 'ringo']
    >>> page2.has_next()     #是否有下一页
    False
    >>> page2.has_previous() #是否有上一页
    True
    >>> page2.has_other_pages() #是否有其他页
    True
    >>> page2.next_page_number() #下一页的页码
    Traceback (most recent call last):
    ...
    EmptyPage: That page contains no results
    >>> page2.previous_page_number()  #上一页的页码
    1
    >>> page2.start_index() # 本页第一条记录的序数(从1开始)
    3
    >>> page2.end_index() # 本页最后录一条记录的序数(从1开始)
    4
     
    >>> p.page(0)       #错误的页,抛出异常
    Traceback (most recent call last):
    ...
    EmptyPage: That page number is less than 1
    >>> p.page(3)       #错误的页,抛出异常
    Traceback (most recent call last):
    ...
    EmptyPage: That page contains no results

    实现一个分页效果:

    Template:

    {% load staticfiles %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <link rel="stylesheet" href="{% static 'bootstrap.css' %}">
    
    </head>
    <body>
    
    
    <div class="container">
    
        <h4>分页器</h4>
        <ul>
    
        {% for book in book_list %}
             <li>{{ book.title }} {{ book.price }}</li>
        {% endfor %}
    
    </ul>
    
    
        <ul class="pagination" id="pager">
    
                     {% if book_list.has_previous %}
                        <li class="previous"><a href="/blog/?page={{ book_list.previous_page_number }}">上一页</a></li>
                     {% else %}
                        <li class="previous disabled"><a href="#">上一页</a></li>
                     {% endif %}
    
    
                     {% for num in paginator.page_range %}
    
                         {% if num == currentPage %}
                           <li class="item active"><a href="/blog/?page={{ num }}">{{ num }}</a></li>
                         {% else %}
                           <li class="item"><a href="/blog/?page={{ num }}">{{ num }}</a></li>
    
                         {% endif %}
                     {% endfor %}
    
    
    
                     {% if book_list.has_next %}
                        <li class="next"><a href="/blog/?page={{ book_list.next_page_number }}">下一页</a></li>
                     {% else %}
                        <li class="next disabled"><a href="#">下一页</a></li>
                     {% endif %}
    
                </ul>
    </div>
    
    
    
    
    </body>
    </html>

    views:

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    from app01.models import *
    def index(request):
    
        '''
        批量导入数据:
    
        Booklist=[]
        for i in range(100):
            Booklist.append(Book(title="book"+str(i),price=30+i*i))
        Book.objects.bulk_create(Booklist)
    
        '''
    
        book_list=Book.objects.all()
    
        paginator = Paginator(book_list, 10)
        page = request.GET.get('page',1)
        currentPage=int(page)
    
    
        try:
            print(page)
            book_list = paginator.page(page)
        except PageNotAnInteger:
            book_list = paginator.page(1)
        except EmptyPage:
            book_list = paginator.page(paginator.num_pages)
    
    
        return render(request,"index.html",locals())

     二、自定义分页器

      分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户输入计算出应该在数据看中的使其位置。

      1.设定每页显示数据条数

      2.用户输入页码(第一页、第二页。。。)

      3.根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置

      4.在数据表中根据其实位置取值,页面上取出数据


      需求又来了,需要在页面上显示分页的页面。如:[ 上一页 ] [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 下一页 ]

      1.设定每页显示数据条数

      2.用户输入页码(第一页、第二页。。。)

      3.设定显示多少页号

      4.获取当前数据总条数

      5.根据设定显示多少页号和数据总条数计算出总页数

      6.根据设定的每页显示条数和当前页码,计算出需要取是数据表的起始位置

      7.在数据表中根据其实位置取值,页面上输出数据

      8.输出分页html,如:[ 上一页 ] [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 下一页 ]

    """
    使用方法:
    
    from utils.page import Pagination
    def users(request):
        current_page = int(request.GET.get('page',1))
    
        total_item_count = models.UserInfo.objects.all().count()
        # page_obj = Pagination(current_page,total_item_count,request.path_info)
        page_obj = Pagination(current_page,total_item_count,'/users.html')
    
        user_list = models.UserInfo.objects.all()[page_obj.start:page_obj.end]
    
        return render(request,'users.html',{'user_list':user_list,'page_html':page_obj.page_html()})
    
    
    """
    
    
    from django.utils.safestring import mark_safe
    
    class Pagination(object):
      def__init__(self,current_page,total_item_count,base_url,per_page_count=10,show_pager_count=11):
            """
            :param current_page:  当前页
            :param total_item_count: 数据库数据总条数
            :param base_url: 分页前缀URL
            :param per_page_count:   每页显示数据条数
            :param show_pager_count: 对多显示的页码
            """
            self.current_page = current_page
            self.total_item_count = total_item_count
            self.base_url = base_url
            self.per_page_count = per_page_count
            self.show_pager_count = show_pager_count
    
            max_pager_num, b = divmod(total_item_count, per_page_count)
            if b:
                max_pager_num += 1
            self.max_pager_num = max_pager_num
    
        @property
        def start(self):
            """
    
            :return:
            """
            return (self.current_page-1)* self.per_page_count
    
        @property
        def end(self):
            """
    
            :return:
            """
            return self.current_page * self.per_page_count
    
        def page_html(self):
            """
    
            :return:
            """
            page_list = []
    
            if self.current_page == 1:
                prev = ' <li><a href="#">上一页</a></li>'
            else:
                prev = ' <li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,)
            page_list.append(prev)
    
            half_show_pager_count = int(self.show_pager_count / 2)
    
            # 数据特别少,15条数据=2页
            if self.max_pager_num < self.show_pager_count:
                # 页码小于11
                pager_start = 1
                pager_end = self.max_pager_num + 1
            else:
                if self.current_page <= half_show_pager_count:
                    pager_start = 1
                    pager_end = self.show_pager_count + 1
                else:
                    if self.current_page + half_show_pager_count > self.max_pager_num:
                        pager_start = self.max_pager_num - self.show_pager_count + 1
                        pager_end = self.max_pager_num + 1
                    else:
                        pager_start = self.current_page - half_show_pager_count
                        pager_end = self.current_page + half_show_pager_count + 1
    
            for i in range(pager_start, pager_end):
                if i == self.current_page:
                    tpl = ' <li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
                else:
                    tpl = ' <li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
                page_list.append(tpl)
    
            if self.current_page == self.max_pager_num:
                nex = ' <li><a href="#">下一页</a></li>'
            else:
                nex = ' <li><a href="%s?page=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)
            page_list.append(nex)
    
            return mark_safe(''.join(page_list))
    分页实例

    总结,分页时需要做三件事:

    • 创建处理分页数据的类
    • 根据分页数据获取数据
    • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]
  • 相关阅读:
    目录拷贝
    获取当前时间
    获取当前目录名称
    WPF 修改数据后更新UI
    外网访问FTP服务,解决只能以POST模式访问Filezilla的问题
    解决Postgresql服务启动又关闭的问题
    更换PostgreSql的data文件夹并重新服务器(此方法同样适用于系统崩溃后,找回数据的操作)
    C#一键显示及杀死占用端口号进程
    [WP8开发] WinJS中winControl或者itemDataSource值为null的解决方案
    [WP8开发] WebBrowser控件与后台代码.cs简单的交互
  • 原文地址:https://www.cnblogs.com/78pikaqiu/p/7455046.html
Copyright © 2011-2022 走看看