柴少的博客 也许终将一事无成,却不能甘于平庸。

Django之中间件(十三)

一、中间件介绍

1.1 中间件简介

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
中间件共分为:

process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

中间件顺序:

中间件是嵌入 django 的 request/response 处理过程的一套钩子框架。它是一个轻量级的底层嵌入系统,可以对 django 的输入输出做整体的修改。

图片.png

也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。
中间件不用继承自任何类(可以继承 object ),下面一个中间件大概的样子:

class CommonMiddleware(object):
    def process_request(self, request):
        return None

    def process_response(self, request, response):
        return response

使用方法 :

 Django中间件必须是一个类,不需要继承任何类,并提供四个接口:

process_request(self, request)该方法在请求到来的时候调用。 
process_view(self ,request, fnc , arg ,kwarg)在本次将要执行的View函数被调用前调用本函数。 
process_response(self,request,response)在执行完View函数准备将响应发到客户端前被执行。 
**process_exception(self,request, exception)**View函数在抛出异常时该函数被调用,得到的exception参数是实际上抛出的异常实例。通过此方法可以进行很好的错误控制,提供友好的用户界面。

二、自定义中间件

2.1 中间件之process_request,process_response

process_request(self,request)
process_response(self, request, response)
当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者
在django中叫中间件,在其他web框架中,有的叫管道,httphandle

图片.png

 创建自定义类

我们可以自己写一个类,但是必须继承MiddlewareMixin。所以需要导入:from django.utils.deprecation import MiddlewareMixin
我们在项目文件下创建一个Middle目录,并在下面创建m1.py代码例子如下:

图片.png

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Row1(MiddlewareMixin):
    def process_request(self,request):
        print('中间件1请求')
    def process_response(self, request, response):
        print('中间件1返回')
        return response

class Row2(MiddlewareMixin):
    def process_request(self,request):
        print('中间件2请求')
        # return HttpResponse('走')
    def process_response(self, request, response):
        print('中间件2返回')
        return response

class Row3(MiddlewareMixin):
    def process_request(self,request):
        print('中间件3请求')
    def process_response(self, request, response):
        print('中间件3返回')
        return response

注册中间件

settings.py:

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',
    'Middle.m1.Row1',   #在这里添加就是注册中间件,这就定位到了Middle目录下的m1下的Row1
    'Middle.m1.Row2',
    'Middle.m1.Row3',
]

其他设置:

urls.py:

url(r'^test/$', views.test),

views.py:

def test(request):
    print('中间件测试')
    return  HttpResponse('OK')

测试一下:

#前端url访问以下:http://127.0.0.1:8000/test/

图片.png

#从上图可以看到,用户有访问请求,会从中间件最上方的request(接收)一直往下执行,最后到视图函数然后再由中间件从下往上的response(返回)给用户。

2.2 中间件之process_view

创建自定义类:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Row1(MiddlewareMixin):
    def process_request(self,request):
        print('中间件1请求')
    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        print('中间件1view')
    def process_response(self, request, response):
        print('中间件1返回')
        return response

class Row2(MiddlewareMixin):
    def process_request(self,request):
        print('中间件2请求')
        # return HttpResponse('走')
    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    #view_func, view_func_args, view_func_kwargs都是views函数里面的参数
        print('中间件2view')
    def process_response(self, request, response):
        print('中间件2返回')
        return response

class Row3(MiddlewareMixin):
    def process_request(self,request):
        print('中间件3请求')
    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        print('中间件3view')
    def process_response(self, request, response):
        print('中间件3返回')
        return response

    def process_exception(self, request, exception):  #对views的报错做特殊处理。当出错的时候会执行这里
        if isinstance(exception,ValueError):   #当出现isinstance这个错误的时候,就返回下面的内容
            return HttpResponse('出现异常》。。')

    def process_template_response(self,request,response):
        #默认也是不执行的,如果Views中的函数返回的对象中,具有render方法
        print('-----------------------')
        return response

图片.png

#可以看到request完事之后又折回来执行view,然后再到views函数返回,然后再是response。

views.py函数也改一改:

class Foo:
    def __init__(self,req,html,dic):
        self.req = req
        self.html = html
        self.dic = dic
    def render(self):
        # // 创建钩子
        return render(self.req,self.html,self.dic)
def test(request,nid):
    print('中间件测试')
    # return render(request, 'index.html', {...})
    return Foo(request, 'index.html', {'k1': 'v1'})

图片.png

作者:chaishaopeng 分类:Django学习 浏览:1225 评论:0
留言列表
发表评论
来宾的头像