zoukankan      html  css  js  c++  java
  • Django学习---中间件

    中间件

    之前我们说django的生命周期:url ->  路由系统  ->函数或者类 -> 返回字符串 或者 模板语言,其实前面还有很多的操作。

    django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

    在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下:

    settings.py

    1 MIDDLEWARE = [
    2     'django.middleware.security.SecurityMiddleware',
    3     'django.contrib.sessions.middleware.SessionMiddleware',
    4     'django.middleware.common.CommonMiddleware',
    5     'django.middleware.csrf.CsrfViewMiddleware',
    6     'django.contrib.auth.middleware.AuthenticationMiddleware',
    7     'django.contrib.messages.middleware.MessageMiddleware',
    8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
    9 ]

     执行过程:

    请求要从中间件穿过,然后返回的时候再从中间件穿出。

    自定义中间件

    1、创建中间件类

     创建一个目录Middle,下面写一个m1.py:

     1 from django.utils.deprecation import MiddlewareMixin
     2 
     3 class Row1(MiddlewareMixin):
     4     def process_request(self,request):
     5         print("first...")
     6 
     7 class Row2(MiddlewareMixin):
     8     def process_request(self,request):
     9         print("second...")
    10 class Row3(MiddlewareMixin):
    11     def process_request(self,request):
    12         print("third...")

    2、注册中间件

     1 MIDDLEWARE = [
     2     'django.middleware.security.SecurityMiddleware',
     3     'django.contrib.sessions.middleware.SessionMiddleware',
     4     'django.middleware.common.CommonMiddleware',
     5     'django.middleware.csrf.CsrfViewMiddleware',
     6     'django.contrib.auth.middleware.AuthenticationMiddleware',
     7     'django.contrib.messages.middleware.MessageMiddleware',
     8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     9     'Middle.m1.Row1',
    10     'Middle.m1.Row2',
    11     'Middle.m1.Row3',
    12 ]

     view.py:

    1 def test(request):
    2     print("返回的信息。。。")
    3     return HttpResponse('ok')

    我们运行,返回的结果是:

    这个请求是经过中间件中所有的process_request方法,那也应该有一个response

     1 from django.utils.deprecation import MiddlewareMixin
     2 
     3 class Row1(MiddlewareMixin):
     4     def process_request(self,request):
     5         print("first...")
     6     def process_response(self,request,response):
     7         print("first response")
     8         return response
     9 
    10 class Row2(MiddlewareMixin):
    11     def process_request(self,request):
    12         print("second...")
    13     def process_response(self,request,response):
    14         print("second response")
    15         return response
    16 
    17 class Row3(MiddlewareMixin):
    18     def process_request(self,request):
    19         print("third...")
    20     def process_response(self,request,response):
    21         print("third response")
    22         return response

     我们要注意,process_response中的参数request,response的名字和顺序都不能够错,否则就会出现错误。

    那现在我们来看看我们运行的效果是什么样子的 :

    那这个就是中间件执行的顺序过程。

    那中间件有什么用呢?

    我们可以看到这个参数有request和response,那这个request就是view中的函数中的参数request,我们通过它可以获得method,post值等。所以我们可以做这个样的事情:判断一下发来请求有没有带请求头,如果没有带请求头,那就不需要继续往下走了,直接在中间件中就停止。

    比如:我们上面的三个中间件,我们的请求经过了第一个Row1,下面到Row2,如果我们在这里面做一个判断:如果没有带请求头的话就直接return,我们看看怎么执行的? 

    1 from django.shortcuts import HttpResponse
    2 class Row2(MiddlewareMixin):
    3     def process_request(self,request):
    4         print("second...")
    5         return HttpResponse("停止")
    6     def process_response(self,request,response):
    7         print("second response")
    8         return response

     你看,这个就直接跳过了third,然后返回

     

    这个就是整个请求周期,我们可以发现在前面还有一大堆的东西挡着,这个中间件适合于对所有的请求进行一个统一的操作,如公共校验,黑名单过滤:获取一下用户的ip,如果在黑名单里就不让它访问,直接在中间件中组织了,没有必要执行下面的操作。

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

    我们现在在上面的中间件中在加入一个方法process_view:

     1 from django.utils.deprecation import MiddlewareMixin
     2 
     3 class Row1(MiddlewareMixin):
     4     def process_request(self,request):
     5         print("first...")
     6 
     7     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
     8         print("first process_view")
     9 
    10     def process_response(self,request,response):
    11         print("first response")
    12         return response
    13 
    14 from django.shortcuts import HttpResponse
    15 class Row2(MiddlewareMixin):
    16     def process_request(self,request):
    17         print("second...")
    18 
    19     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    20         print("second process_view")
    21 
    22     def process_response(self,request,response):
    23         print("second response")
    24         return response
    25 
    26 class Row3(MiddlewareMixin):
    27     def process_request(self,request):
    28         print("third...")
    29 
    30     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    31         print("third process_view")
    32 
    33     def process_response(self,request,response):
    34         print("third response")
    35         return response

     下面我们再来看看执行的结果:

    由上面的显示结果我们可以看到的运行流程是,先执行process_request,匹配了url路由之后,折回来在执行process_view,执行views.py中的函数,之后再执行process_response

     process_view里面的参数实际上就是views.py里面的函数的函数名和参数,如果我们在url中添加的是正则匹配,那后面就要用一个参数接收一下。

     process_exception(self, request, exception)如果views中的函数执行错误了就执行该方法

     m1.py

     1 class Row3(MiddlewareMixin):
     2     def process_request(self,request):
     3         print("third...")
     4 
     5     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
     6         print("third process_view")
     7 
     8     def process_response(self,request,response):
     9         print("third response")
    10         return response
    11     def process_exception(self, request, exception):
    12         if isinstance(exception,ValueError):
    13             return HttpResponse("出现异常了。。。。")

     views.py:

    1 def test(request):
    2     int("asdfasdf")
    3     print("返回的信息。。。")
    4     return HttpResponse('ok')

     上面的views.py中的函数很明显有一个错误,如果正常情况下执行肯定会报错,但是我们在中间件中进行了处理,那么我们在执行的时候就会返回一个出现异常。。。。

    所以这个东西就可以对异常,报错进行处理,但是如果views.py中没有出错,那么就不会被执行

    process_template_response(self,request,response)

     默认也不执行,如果views中的函数返回的对象中,具有render方法,那就默认会执行

    views.py:

    1 class Foo:
    2     def render(self):
    3         return HttpResponse("ok")
    4 def test(request):
    5 
    6     print("返回的信息。。。")
    7     return Foo()

    m1.py:

     1 class Row3(MiddlewareMixin):
     2     def process_request(self,request):
     3         print("third...")
     4 
     5     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
     6         print("third process_view")
     7 
     8     def process_response(self,request,response):
     9         print("third response")
    10         return response
    11     def process_exception(self, request, exception):
    12         if isinstance(exception,ValueError):
    13             return HttpResponse("出现异常了。。。。")
    14     def process_template_response(self,request,response):
    15         print("process_template_response函数执行")
           return response

    运行结果:

     

  • 相关阅读:
    C++Josephus问题
    C++背包示例
    C++1000以内的质数
    as3+asp+access编码
    fb设置flashplayer
    三视图示例
    正确实现 IDisposable 接口
    .net垃圾回收和CLR 4.0对垃圾回收所做的改进之二
    .net垃圾回收和CLR 4.0对垃圾回收所做的改进之三
    CLR 全面透彻解析:大型对象堆揭秘
  • 原文地址:https://www.cnblogs.com/charles8866/p/8870840.html
Copyright © 2011-2022 走看看