博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django组件——分页器和中间件
阅读量:5089 次
发布时间:2019-06-13

本文共 11819 字,大约阅读时间需要 39 分钟。

分页器

Django内置分页器(paginator)

分页器函数为paginator,里面有几个重要的参数需要我们了解

paginator = Paginator(book_list, 10)      #第二个参数表示每页显示的数量    paginator.count)                          #数据总数    paginator.num_pages                       #总页数    paginator.page_range                      #页码的列表    page1=paginator.page(1)                   #第1页的page对象    for i in page1:                           #遍历第1页的所有数据对象        print(i)    print(page1.object_list)                  #第1页的所有数据    page2=paginator.page(2)    print(page2.has_next())                   #是否有下一页,返回布尔值    print(page2.next_page_number())           #下一页的页码    print(page2.has_previous())               #是否有上一页,返回布尔值    print(page2.previous_page_number())       #上一页的页码    # 不存在时会抛错    #page=paginator.page(12)                  # error:EmptyPage    #page=paginator.page("z")                 # error:PageNotAnInteger

 

在views中:

from django.shortcuts import render,HttpResponsefrom app01.models import *from django.core.paginator import Paginator, EmptyPage, PageNotAnIntegerdef index(request):    '''     这里我们伪造数据库的数据,假设从数据库获得了100条数据     批量导入数据:    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)           #数据总数    print("num_pages",paginator.num_pages)    #总页数    print("page_range",paginator.page_range)  #页码的列表    page1=paginator.page(1) #第1页的page对象    for i in page1:         #遍历第1页的所有数据对象        print(i)    print(page1.object_list) #第1页的所有数据    page2=paginator.page(2)    print(page2.has_next())             #是否有下一页,返回布尔值    print(page2.next_page_number())     #下一页的页码    print(page2.has_previous())         #是否有上一页,返回布尔值    print(page2.previous_page_number()) #上一页的页码    # 不存在时会抛错    #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) #前端传的页码数,默认值为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",{
"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
后端数据处理

 

在template下的index.html中:

    
Title
  

分页器

  
        {% for book in book_list %}      
  • {
    { book.title }} -----{
    { book.price }}
  •     {% endfor %}  
  
        {% if book_list.has_previous %}      
        {% else %}      
        {% endif %}    {% for num in paginator.page_range %}      {% if num == currentPage %}        
  • {
    { num }}
  •       {% else %}        
  • {
    { num }}
  •       {% endif %}    {% endfor %}    {% if book_list.has_next %}      
        {% else %}      
        {% endif %}  
前端页面

 

内置分页器的扩展

  当数据量特别多造成分页显示页码也特别多的情况下(比如总共有100页),我们就不能把所有的页码展示出来了,不然网页会显得不好看,这时我们就需要将上面的代码进行优化

def index(request):    book_list=Book.objects.all()    paginator = Paginator(book_list, 15)    page = request.GET.get('page',1)    currentPage=int(page)    #  如果页数十分多时,换另外一种显示方式    if paginator.num_pages>30:        if currentPage-5<1:                pageRange=range(1,11)    #1 2 3 4 5 6 7 8 9 10         elif currentPage+5>paginator.num_pages:             pageRange=range(currentPage-5,paginator.num_pages+1)#91 92 93 94 95 96 97 98 99 100        else:            pageRange=range(currentPage-5,currentPage+5)  #23 24 25 26 27 28 29 30 31 32 33    else:        pageRange=paginator.page_range#总页数小于30时就全部显示    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())
views优化

 

自定义分页器

"""分页组件使用示例:    obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)    page_user_list = USER_LIST[obj.start:obj.end]    page_html = obj.page_html()    return render(request,'index.html',{'users':page_user_list,'page_html':page_html})"""class Pagination(object):    def __init__(self,current_page,all_count,base_url,per_page_num=2,pager_count=11):        """        封装分页相关数据        :param current_page: 当前页        :param all_count:    数据库中的数据总条数        :param per_page_num: 每页显示的数据条数        :param base_url: 分页中显示的URL前缀        :param pager_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 = all_count        self.per_page_num = per_page_num        self.base_url = base_url        # 总页码        all_pager, tmp = divmod(all_count, per_page_num)        if tmp:            all_pager += 1        self.all_pager = all_pager        self.pager_count = pager_count        self.pager_count_half = int((pager_count - 1) / 2)    @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.pager_count:            pager_start = 1            pager_end = self.all_pager + 1        # 总页码  > 11        else:            # 当前页如果<=页面上最多显示11/2个页码            if self.current_page <= self.pager_count_half:                pager_start = 1                pager_end = self.pager_count + 1            # 当前页大于5            else:                # 页码翻到最后                if (self.current_page + self.pager_count_half) > self.all_pager:                    pager_end = self.all_pager + 1                    pager_start = self.all_pager - self.pager_count + 1                else:                    pager_start = self.current_page - self.pager_count_half                    pager_end = self.current_page + self.pager_count_half + 1        page_html_list = []        first_page = '
  • 首页
  • ' % (self.base_url,1,) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '
  • 上一页
  • ' else: prev_page = '
  • 上一页
  • ' % (self.base_url,self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '
  • %s
  • ' % (self.base_url,i, i,) else: temp = '
  • %s
  • ' % (self.base_url,i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '
  • 下一页
  • ' else: next_page = '
  • 下一页
  • ' % (self.base_url,self.current_page + 1,) page_html_list.append(next_page) last_page = '
  • 尾页
  • ' % (self.base_url,self.all_pager,) page_html_list.append(last_page) return ''.join(page_html_list)
    封装在类中,方便以后插入项目中调用

     

     

    中间件

      中间件的概念: 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变Django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

      中间件是建立在用户访问网站时,输入url到视图函数views之间的,如果没通过中间件就无法进入视图层操作,通常会返回一个提示信息。所以中间件的一大应用就是认证用户是否登录。

    Django默认中间件middleware:每一个中间件都有具体的功能。

    MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',]

     

    中间件有四个方法——process_request、process_response、process_view和process_exception,了解了这四个方法以后我们就可以自己自定义中间件。

    process_request和process_response

      当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求是process_request,后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

      上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

    #在views中随便写个视图函数def index(request):    print("view函数...")    return HttpResponse("OK")#自定义中间件#在Mymiddlewares.py中from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponse#自定义中间件一class Md1(MiddlewareMixin):    def process_request(self,request):        print("Md1请求")     def process_response(self,request,response):        print("Md1返回")        return response#自定义中间件二class Md2(MiddlewareMixin):    def process_request(self,request):        print("Md2请求")        #return HttpResponse("Md2中断")    def process_response(self,request,response):        print("Md2返回")        return response"""结果:Md1请求Md2请求view函数...Md2返回Md1返回"""

    如果当请求到达请求2的时候直接不符合条件返回,即return HttpResponse("Md2中断"),程序将把请求直接发给中间件2返回而不经过视图函数,然后依次返回到请求者,所以打印结果如下:

    Md1请求Md2请求Md2返回Md1返回

    中间件流程图如下:

             

    process_view

      process_view是在请求经过process_request到达url映射关系后,views函数处理之前执行的函数

    下图进行分析process_view的过程:

      当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

    from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponseclass Md1(MiddlewareMixin):    def process_request(self,request):        print("Md1请求")        #return HttpResponse("Md1中断")    def process_response(self,request,response):        print("Md1返回")        return response    def process_view(self, request, callback, callback_args, callback_kwargs):        print("Md1view")class Md2(MiddlewareMixin):    def process_request(self,request):        print("Md2请求")        return HttpResponse("Md2中断")    def process_response(self,request,response):        print("Md2返回")        return response    def process_view(self, request, callback, callback_args, callback_kwargs):        print("Md2view")"""Md1请求Md2请求Md1viewMd2viewview函数...Md2返回Md1返回"""

     

     process_view可以用来调用视图函数:

     

    class Md1(MiddlewareMixin):    def process_request(self,request):        print("Md1请求")        #return HttpResponse("Md1中断")    def process_response(self,request,response):        print("Md1返回")        return response    def process_view(self, request, callback, callback_args, callback_kwargs):        # return HttpResponse("hello")        response=callback(request,*callback_args,**callback_kwargs)        return response"""Md1请求Md2请求view函数...Md2返回Md1返回"""

    注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。

     

    process_exception

    示例修改如下:

    class Md1(MiddlewareMixin):    def process_request(self,request):        print("Md1请求")        #return HttpResponse("Md1中断")    def process_response(self,request,response):        print("Md1返回")        return response    def process_view(self, request, callback, callback_args, callback_kwargs):        # return HttpResponse("hello")        # response=callback(request,*callback_args,**callback_kwargs)        # return response        print("md1 process_view...")    def process_exception(self):        print("md1 process_exception...")class Md2(MiddlewareMixin):    def process_request(self,request):        print("Md2请求")        # return HttpResponse("Md2中断")    def process_response(self,request,response):        print("Md2返回")        return response    def process_view(self, request, callback, callback_args, callback_kwargs):        print("md2 process_view...")    def process_exception(self):        print("md1 process_exception...")"""Md1请求Md2请求md1 process_view...md2 process_view...view函数...Md2返回Md1返回"""

    流程图如下:

    当views出现错误时:

              

     将md2的process_exception修改如下:

     

    def process_exception(self,request,exception):    print("md2 process_exception...")    return HttpResponse("error")

    结果如下:

    Md1请求Md2请求md1 process_view...md2 process_view...view函数...md2 process_exception...Md2返回Md1返回

     

                                      

     

     

     

     

     

                             

    转载于:https://www.cnblogs.com/zhuminghui/p/8387176.html

    你可能感兴趣的文章
    SQL Server 使用作业设置定时任务之一(转载)
    查看>>
    第二阶段冲刺-01
    查看>>
    BZOJ1045 HAOI2008 糖果传递
    查看>>
    JavaScript 克隆数组
    查看>>
    eggs
    查看>>
    python3 生成器与迭代器
    查看>>
    java编写提升性能的代码
    查看>>
    《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇03:暂停游戏》
    查看>>
    CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
    查看>>
    git .gitignore 文件不起作用
    查看>>
    Alan Turing的纪录片观后感
    查看>>
    IOS--沙盒机制
    查看>>
    使用 JointCode.Shuttle 访问任意 AppDomain 的服务
    查看>>
    sqlite的坑
    查看>>
    digitalocean --- How To Install Apache Tomcat 8 on Ubuntu 16.04
    查看>>
    【题解】[P4178 Tree]
    查看>>
    Mongo自动备份
    查看>>
    cer证书签名验证
    查看>>
    synchronized
    查看>>
    【深度学习】caffe 中的一些参数介绍
    查看>>