WEB框架-Django组件学习-分页器学习

1.分页器基础学习

1.1 补充知识-批量建立

数据库中数据批量建立,不要每建立一个就往数据库中塞一个,会形成撞库,形成大量I/O操做,速速较慢,应该采用一次性建立大量数据,一次性将大量数据塞入到数据库中。css

主要用到:库名.objects.bulk_create(数据)html

def index(request):
    book_list=[]
    for i in range(1,101):
        book = Book(title="book%s"%i,price=i*i)
        book_list.append(book)

    # 数据批量添到数据库中
    Book.objects.bulk_create(book_list)
    return HttpResponse("ok")

展现以下前端

image

image

1.2 django自带分页器组件

1.2.1 django经常使用参数

#分页器组件导入
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger

#全局信息查询

paginator = Paginator(book_obj,10) :分页对象,俩个参数,第一个为数据,第二个为每页展现的数量  
paginator.count:  展现分页的数据大小
paginator.num_pages:展现总计分页数量
paginator.page_range :相似range的数据类型

#单页信息查询

page = paginator.page(1)#页面对象
page.object_list#打印当前页面的数据量大小
page.has_next()#是否有下一页
page.has_previous()#是否有上一页
page.next_page_number()#当前页的上一页的页码是多少
page.previous_page_number()#当前页的下一页的页码是多少

1.2.2 其余参数数据库

 

1.3 分页器的基本应用

1.3.1 分页展现数据

def book_list(request):
  
    book_obj = Book.objects.all()
    # 分页器对象
    paginator = Paginator(book_obj,10)
    # 获取当前页码
    current_page = int(request.GET.get("page"))
    # 实例一个页面对象
    page = paginator.page(current_page)



    return render(request,'book_list.html',locals())
#须要注意的是:在模板层记得更改循环的对象

展现以下npm

image

1.3.2 错误页展现

对于超出的页码以及错误输入默认展现第一页django

image

展现以下,错误跳转以及默认跳转bootstrap

imageimage

1.3.3 页面页码显示

页面页码展现主要是模板层代码改变app

首先调用bootstrap,或文件或cdnide

image

页面展现函数

image

1.3.4 上一页,下一页功能

上一页,下一页功能实现,主要用

page.has_next()#是否有下一页
page.has_previous()#是否有上一页
page.next_page_number()#当前页的上一页的页码是多少
page.previous_page_number()#当前页的下一页的页码是多少

展现以下

image

视图层完整代码

def book_list(request):

    book_obj = Book.objects.all()
    # 分页器对象
    paginator = Paginator(book_obj,10)
    try:
        # 获取当前页码,后面默认页为1
        current_page = int(request.GET.get("page"))
        # 实例一个页面对象
        page = paginator.page(current_page)
    # 错误页码默认跳转到首页
    except EmptyPage as e:
        page = paginator.page(1)

    return render(request,'book_list.html',locals())
视图层

模板层完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>展现数据</h3>
<ul>
    {% for foo in page %}
        <li>{{ foo }}</li>

    {% endfor %}

</ul>
<nav aria-label="Page navigation">
  <ul class="pagination">
    {% if page.has_previous %}
        <li>
            <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">上一页</span>
          </a>
        </li>
    {% else %}
        <li class="disabled">
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">上一页</span>
          </a>
    </li>

    {% endif %}
        {% for num in paginator.page_range %}
            {% 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>
模板层

1.4 分页器的高阶应用

1.4.1 动态加载页码

多余多数据的时候,动态的展现页码,例如博客园的样式

image

逻辑展现

主要模仿博客园这样,在小于必定页数,默认展现10页,在超过必定页数,展现左5与右5的页码,到最后的必定页面,固定展现必定页数

  • 当总页码小于11页时,pageRange = paginator.page_range,展现全部页码便可
  • 当页码大于11页时,
    • 当当前页码-5<1时,固定展现:pageRange = range(1,11)
    • 当当前页码+5>最大页码,展现最后11页:pageRange=range(paginator.num_pages-10,paginator.num_pages+1)
    • 其余则正常显示,左5与右5页码:pageRange=range(current_page - 5,current_page+6)

image

2.模仿django分页器实现本身的分页器组件

2.1 基本展现数据

image

展现以下,又变成了最开始的样子。。。。。

image

2.2 自定义页码展现

2.2.1 页码逻辑设置

image

处理逻辑和以前的一致,不过有部分区别就是不在 是固定的页码,反而是动态的获取

2.2.2 前端页面书写

在一样的函数体内书写

image

模板层

image

最后展现

image

2.3 保留搜索条件

保留搜索条件主要是用于后面用于serch,action,分类时调用参数使用,因此须要保留搜索条件

2.3.1 补充知识点

querydict字典,默认不能编辑

image

结果报错

image

若是想要编辑就须要导入包,进行深copy操做

image

在源码中若是是作copy操做则能够编辑

image

将querydict的操做转换为字符串操做

image

2.3.2 保留搜索条件

保留搜索条件的逻辑

image

展现以下

image

视图层所有代码

from django.shortcuts import render,HttpResponse

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

####################################自定义组件########################################
class Pagination(object):
    def __init__(self,request,current_page,all_data,per_page_num,max_page_count=13):
        '''
        current_page :当前页码
        all_count:数据总大小
        per_page_num:每页展现数量
        max_page_count:最大分页数
        '''
        # 若是获取非数字
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        #若是获取小于1的数字
        if current_page<1:
            current_page = 1

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

        # 总页码
        all_pager,temp = divmod(self.all_count,self.per_page_num)
        if temp:
            all_pager +=1
        self.all_pager = all_pager

        # 最大展现页码以及左右最大展现页码
        self.max_page_count = max_page_count
        self.half_page_count = int((self.max_page_count-1)/2)
        self.request = request

        # 复制的字典
        import copy
        self.params = copy.deepcopy(self.request.GET)



    # 获取切片数据的初始以及结束
    @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):
        #if 页码大于11时
        if self.all_pager >self.max_page_count:
            if self.current_page<=self.half_page_count:
                pagerange=range(1,self.max_page_count+1)
            elif self.current_page+self.half_page_count > self.all_pager:
                pagerange = range(self.all_pager-self.max_page_count+1,self.all_pager+1)
            else:
                pagerange= range(self.current_page-self.half_page_count,self.current_page+self.half_page_count+1)
        else:
            #页码没有大于11
            pagerange= range(1,self.all_pager+1)

        # 构建分页页码的html
        page_html_list = []
        # 首页
        self.params["page"] = 1
        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
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        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
            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
        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 book_list2(request):

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

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

    return render(request,'book_list2.html',locals())
视图层代码

模板层所有代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

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

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


</body>
</html>
模板层代码

a