crm03 分页

一、Django的分页器(paginator)

from django.db import models

# Create your models here.


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()

    def __str__(self):return self.title
app01/models.py

 paginator类的基本属性与方法

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

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)  #每页显示的数据的个数
    print("count:",paginator.count)           #数据总数  count: 100
    print("num_pages:",paginator.num_pages)    #总页数  num_pages: 10
    print("page_range:",paginator.page_range)  #页码的列表eg:100条数据 如果设置每页显示10条 page_range: range(1, 11); 如果设置每页显示5条 page_range: range(1, 21);



    page1=paginator.page(1) #第1页的page对象
    print(page1) #<Page 1 of 10>
    for i in page1:         #遍历第1页的所有数据对象
        print(i)# book_1    # book_2      # book_3  # book_4    # book_5   # book_6     # book_7    # book_8    # book_9    # book_10

    print(page1.object_list) #第1页的所有数据对象 #[<Book: book_1>, <Book: book_2>, <Book: book_3>, <Book: book_4>, <Book: book_5>, <Book: book_6>, <Book: book_7>, <Book: book_8>, <Book: book_9>, <Book: book_10>]


    page2=paginator.page(2)

    print(page2.has_next())            #是否有下一页 True
    print(page2.next_page_number())    #下一页的页码  3
    print(page2.has_previous())        #是否有上一页 True
    print(page2.previous_page_number()) #上一页的页码 1



    # 抛错
    #page=paginator.page(12)   # error:EmptyPage

    #page=paginator.page("z")   # error:PageNotAnInteger
    #
    # '''
    return HttpResponse('okok')

小栗子

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def index(request):

    # 抛错
    #page=paginator.page(12)   # error:EmptyPage
    #page=paginator.page("z")   # error:PageNotAnInteger

    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,"index0.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
app01/views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<link rel="stylesheet" href="/static/bootstrap/css/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="/index0/?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="/index0/?page={{ num }}">{{ num }}</a></li>
                     {% else %}
                       <li class="item"><a href="/index0/?page={{ num }}">{{ num }}</a></li>

                     {% endif %}
                 {% endfor %}



                 {% if book_list.has_next %}
                    <li class="next"><a href="/index0/?page={{ book_list.next_page_number }}">下一页</a></li>
                 {% else %}
                    <li class="next disabled"><a href="#">下一页</a></li>
                 {% endif %}

            </ul>
</div>



</body>
</html>
templates/index0.html

二、扩展

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def index(request):

    book_list = Book.objects.all()
    paginator = Paginator(book_list, 5)
    try:
        current_page=int(request.GET.get("page",1))
        page = paginator.page(current_page)

        if paginator.num_pages > 11:

            if current_page - 5 < 1:
                pageRange = range(1, 12)
            elif current_page + 5 > paginator.num_pages:
                pageRange = range(paginator.num_pages - 10, paginator.num_pages + 1) #range()取不到尾 所以+1
            else:
                pageRange = range(current_page - 5, current_page + 6)

        else:
            pageRange = paginator.page_range #总页数小于等于11 用它本身的range
    except EmptyPage as e:
        page = paginator.page(1)


    return render(request,"index.html",locals())
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</head>
<body>

<ul>
    {% for book in page %}
    <li>{{ book }}</li>
    {% endfor %}

</ul>


<nav aria-label="Page navigation">
  <ul class="pagination">
    <li>
      <a href="#" aria-label="Previous">
        <span aria-hidden="true">上一页</span>
      </a>
    </li>

      {% for num in pageRange %}
             {% if current_page == num %}
                 <li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
             {% else %}
                 <li><a href="?page={{ num }}">{{ num }}</a></li>
             {% endif %}

      {% endfor %}

    {% if page.has_next %}
    <li>
      <a href="?page={{ page.next_page_number }}" aria-label="Next">
        <span aria-hidden="true">下一页</span>
      </a>
    </li>
    {% else %}
     <li class="disabled">
      <a href="#" aria-label="Next">
        <span aria-hidden="true">下一页</span>
      </a>
    </li>
    {% endif %}

  </ul>
</nav>
</body>
</html>

三、自定义分页器

class Pagination(object):

    def __init__(self,request,current_page,all_data,per_page_num=2,max_page_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    分页数据中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param max_page_count:  最多显示的页码个数
        """

        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1
        if current_page <1:
            current_page = 1

        self.current_page = current_page
        self.all_count = len(all_data)
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(self.all_count, per_page_num)# 除法  商与余数
        if tmp: #余数存在 all_pager 要加1
            all_pager += 1
        self.all_pager = all_pager
        self.max_page_count = max_page_count
        self.max_page_count_half = int((max_page_count - 1) / 2) #

        self.request=request


        #
        import copy
        self.params=copy.deepcopy(self.request.GET)#self.request.GET该字典不能增加和修改,所以copy一个
        print(self.params.urlencode()) #eg:字符串:page=9&a=1

    '''
     all_count=100    per_page_num =10 
        
     current_page        start    end
          1                 0      10
          2                 10     20
          3                 20     30
          
          
      all_count=100    per_page_num =8
        
     current_page        start    end
          1                 0      8
          2                 8      16
          3                 16     24  
          
     表达式:    start= (current_page-1)*per_page_num    end =current_page* per_page_num
    
    '''

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num #当前页的第一条数据

    @property
    def end(self):
        return self.current_page * self.per_page_num ##当前页的最后一条数据

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.max_page_count:
            pageRange=range(1, self.all_pager + 1)  #因为range顾首不顾尾
        # 总页码  > 11
        else:
            # 当前页如果小于页面上最多显示(11-1)/2个页码
            if self.current_page <= self.max_page_count_half:
                pageRange=range(1,self.max_page_count + 1)  #eg:当前页码为3  1,2,   3    4,5,6,7,8,9,10,11  因为self.max_page_count =11  self.max_page_count_half=5
            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.max_page_count_half) > self.all_pager:
                    pageRange=range(self.all_pager-self.max_page_count+1,self.all_pager + 1)#eg:self.current_page当前为16,self.all_pager总页数为20     11-20
                else:
                    pageRange=range(self.current_page - self.max_page_count_half,self.current_page + self.max_page_count_half + 1)#eg:self.current_page当前为10 range(5,16)

        # 构建分页页码的html
        page_html_list = []
        self.params["page"]=1  #修改拷贝的self.request.GET该字典page键值
        first_page = '<nav aria-label="Page navigation"><ul class="pagination"> <li><a href="?%s">首页</a></li>' % (self.params.urlencode(),)
        page_html_list.append(first_page)
        self.params["page"] = self.current_page - 1 # #修改拷贝的self.request.GET该字典page键值
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>' #如果当前页码小于等于1  上一页按钮禁止点击
        else:
            prev_page = '<li><a href="?%s">上一页</a></li>' % (self.params.urlencode(),)

        page_html_list.append(prev_page)
        # self.params: ["page":9,"a":1,"b":2]
        for i in pageRange:
            self.params["page"]=i # #修改拷贝的self.request.GET该字典page键值
            if i == self.current_page:
                temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,) #选择的当前按钮颜色加深
            else:
                temp = '<li><a href="?%s">%s</a></li>' % (self.params.urlencode(),i,)
            page_html_list.append(temp)

        self.params["page"] = self.current_page + 1 # #修改拷贝的self.request.GET该字典page键值
        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'  #如果当前页码大于等于总页数  下一页按钮禁止点击
        else:
            next_page = '<li><a href="?%s">下一页</a></li>' % (self.params.urlencode(),)
        page_html_list.append(next_page)

        self.params["page"]=self.all_pager
        last_page = '<li><a href="?%s">尾页</a></li> </ul></nav>' % (self.params.urlencode())
        page_html_list.append(last_page)

        return ''.join(page_html_list)



def index(request):
    '''
    # request.GET["xxx"]="yyy" # This QueryDict instance is immutable
    from django.http.request import QueryDict
    import copy
    params=copy.deepcopy(request.GET)
    print(params)
    # params["xxx"]="yyy"
    print(params) # <QueryDict: {'page': ['9'], 'a': ['1'], 'xxx': ['yyy']}>
    print(params.urlencode())  # QueryDict------>字符串:page=9&a=1


    :param request:
    :return:
    '''

    print(request.GET) # eg:<QueryDict: {'page': ['9'], 'a': ['1']}>
    print(type(request.GET)) #eg: django.http.request.QueryDict

    book_list = Book.objects.all()
    current_page = int(request.GET.get("page", 1))
    pagination=Pagination(request,current_page,book_list,per_page_num=5)

    book_list=book_list[pagination.start:pagination.end]

    return render(request,"index2.html",locals())
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</head>
<body>

<ul>
    {% for book in book_list %}
    <li>{{ book }}</li>
    {% endfor %}
</ul>


<div>
    {{ pagination.page_html|safe }}
</div>



</body>
</html>
index2.html
原文地址:https://www.cnblogs.com/linux985/p/11130628.html