1.分页器基础学习

1.1 补充知识-批量创建

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

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

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
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")

展示如下

WEB框架-Django组件学习-分页器学习 随笔 第1张

WEB框架-Django组件学习-分页器学习 随笔 第2张

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())
#需要注意的是:在模板层记得更改循环的对象

展示如下

WEB框架-Django组件学习-分页器学习 随笔 第3张

1.3.2 错误页展示

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

WEB框架-Django组件学习-分页器学习 随笔 第4张

展示如下,错误跳转以及默认跳转

WEB框架-Django组件学习-分页器学习 随笔 第5张WEB框架-Django组件学习-分页器学习 随笔 第6张

1.3.3 页面页码显示

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

首先调用bootstrap,或文件或cdn

WEB框架-Django组件学习-分页器学习 随笔 第7张

页面展示

WEB框架-Django组件学习-分页器学习 随笔 第8张

1.3.4 上一页,下一页功能

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

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

展示如下

WEB框架-Django组件学习-分页器学习 随笔 第9张

视图层完整代码

WEB框架-Django组件学习-分页器学习 随笔 第10张
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())
视图层

模板层完整代码

WEB框架-Django组件学习-分页器学习 随笔 第12张
<!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 动态加载页码

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

WEB框架-Django组件学习-分页器学习 随笔 第14张

逻辑展示

主要模仿博客园这样,在小于一定页数,默认展示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)

WEB框架-Django组件学习-分页器学习 随笔 第15张

2.模仿django分页器实现自己的分页器组件

2.1 基本展示数据

WEB框架-Django组件学习-分页器学习 随笔 第16张

展示如下,又变成了最开始的样子。。。。。

WEB框架-Django组件学习-分页器学习 随笔 第17张

2.2 自定义页码展示

2.2.1 页码逻辑设置

WEB框架-Django组件学习-分页器学习 随笔 第18张

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

2.2.2 前端页面书写

在同样的函数体内书写

WEB框架-Django组件学习-分页器学习 随笔 第19张

模板层

WEB框架-Django组件学习-分页器学习 随笔 第20张

最后展示

WEB框架-Django组件学习-分页器学习 随笔 第21张

2.3 保留搜索条件

保留搜索条件主要是用于后面用于serch,action,分类时调用参数使用,所以需要保留搜索条件

2.3.1 补充知识点

querydict字典,默认不能编辑

WEB框架-Django组件学习-分页器学习 随笔 第22张

结果报错

WEB框架-Django组件学习-分页器学习 随笔 第23张

如果想要编辑就需要导入包,进行深copy操作

WEB框架-Django组件学习-分页器学习 随笔 第24张

在源码中如果是做copy操作则可以编辑

WEB框架-Django组件学习-分页器学习 随笔 第25张

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

WEB框架-Django组件学习-分页器学习 随笔 第26张

2.3.2 保留搜索条件

保留搜索条件的逻辑

WEB框架-Django组件学习-分页器学习 随笔 第27张

展示如下

WEB框架-Django组件学习-分页器学习 随笔 第28张

视图层全部代码

WEB框架-Django组件学习-分页器学习 随笔 第29张
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())
视图层代码

模板层全部代码

WEB框架-Django组件学习-分页器学习 随笔 第31张
<!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

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄