• Django-(分页器,中间介)


    Django-进阶

     

    分页

    Django的分页器(paginator)

    view

    复制代码
    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)           #数据总数
        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)
        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})
    复制代码

    index.html:

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" 
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </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="/index/?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="/index/?page={{ num }}">{{ num }}</a></li> {% else %} <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if book_list.has_next %} <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li> {% else %} <li class="next disabled"><a href="#">下一页</a></li> {% endif %} </ul> </div> </body> </html>
    复制代码

    扩展

    复制代码
    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)
            elif currentPage+5>paginator.num_pages:
                pageRange=range(currentPage-5,paginator.num_pages+1)
    
            else:
                pageRange=range(currentPage-5,currentPage+5)
    
        else:
            pageRange=paginator.page_range
    
    
        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())
    复制代码

    中间件

    中间件的概念

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

    Django的中间件的定义:

    1
    Middleware is a framework of hooks into Django’s request/response processing. <br>It’s a light, low-level “plugin” system for globally altering Django’s input or output.

    如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

    可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

    大家可能频繁在view使用request.user吧。 Django想在每个view执行之前把user设置为request的属性,于是就用了一个中间件来实现这个目标。所以Django提供了可以修改request 对象的中间件 AuthenticationMiddleware

    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_view
    
    process_exception
    
    process_response
    复制代码

    process_request,process_response

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

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

    需要导入

    1
    from django.utils.deprecation import MiddlewareMixin

     

    in views:

    def index(request):
    
        print("view函数...")
        return HttpResponse("OK")

    in Mymiddlewares.py:

    复制代码
    from django.utils.deprecation import MiddlewareMixin
    from 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返回,然后依次返回到请求者,结果如下:

    返回Md2中断的页面,后台打印如下:

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

    流程图如下:

     

    process_view

    1
    process_view(self, request, callback, callback_args, callback_kwargs)

     Mymiddlewares.py修改如下

    复制代码
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    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):
            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请求
    Md1view
    Md2view
    view函数...
    Md2返回
    Md1返回
    复制代码

    下图进行分析上面的过程:

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

    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

    1
    process_exception(self, request, 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返回
    复制代码
  • 相关阅读:
    2015.2.27 UltraEdit中显示XML结构
    2015.1.31 DataGridView自动滚动到某行
    2015.1.15 利用函数实现将一行记录拆分成多行记录 (多年想要的效果)
    2015.1.15 利用Oracle函数返回表结果 重大技术进步!
    2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效
    2015.1.8 Left join 左连接
    2015.1.10 解决DataGridView SelectionChanged事件自动触发问题
    delphi 遍历窗口
    delphi 访问 protected 属性 哈哈
    clientdataset 读取excel 如果excel 文件不存在的时候 相应的gird 会不显示数据, 鼠标掠过 gird 格子 才会显示数据。 这是一个bug 哈哈
  • 原文地址:https://www.cnblogs.com/liuchengdong/p/7977058.html
Copyright © 2020-2023  润新知