一,什么是中间件:
中间件是一个用来处理Django的请求和响应的框架级别的钩子。用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
django中的中间件:settings.py里:(一共有7个)
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', ]
MIDDLEWARE配置项是一个列表(列表是有序的,记住这一点,后面你就知道为什么要强调有序二字),列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。
二,自定义中间件:
中间件主要有几个方法:
process_request(self,request)
process_response(self, request, response)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
第一步:在应用中新建一个mymiddleware文件夹,新建一个py文件,导入MiddlewareMixin,
from django.utils.deprecation import MiddlewareMixin
第二步:自定义类,并且继承MiddlewareMixin
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
第三步:在views.py中定义一个视图函数:
def index(request): print("view函数...") return HttpResponse("OK")
第四步:在settings.py中的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', 'app01.mymiddleware.mdzz.MyMiddleware', # 自定义中间件一 'app01.mymiddleware.mdzz.MyMiddleware1'# 自定义中间件二 ]
三,process_request:
1:process_request有一个参数,就是request,这个request和视图函数中的request是一样的(在交给Django后面的路由之前,对这个request对象可以进行一系列的操作)。
2:由于request对象是一样的,所以我们可以对request对象进行一系列的操作,包括request.变量名=变量值,这样的操作,我们可以在后续的视图函数中通过相同的方式即可获取到我们在中间件中设置的值。
3:它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。
总结:
1,中间件的process_request方法是在视图函数之前执行的。
2,按照settings.py中MIDDLEWARE中注册的顺序依次执行。
3,当返回值是Httpresponse对象的时候,直接返回给浏览器,不执行视图函数(从当前中间件原路返回)
4,不同的中间件之间传递的request都是同一个对象。
四,process_response:
1:多个中间件的process_response方法是倒叙执行的。
2:定义process_response的时候,必须传入两个形参:request和response
request:第一次传入的对象
response:视图函数返回的HttpResponse对象(也就是说这是Django后台处理完之后给出一个的一个具体的视图)。该方法的返回值(必须要有返回值)也必须是HttpResponse对象。如果不返回response而返回其他对象,则浏览器不会拿到Django后台给他的视图,而是我的中间件中返回的对象
class MyMiddleware(MiddlewareMixin): def process_request(self,request): print('我是第一个自定义中间件里面的process_request方法') # return HttpResponse('heiheihei') def process_response(self,request,response): print('我是第一个自定义中间件里面的process_response方法') return response # 必须将response形参接收的到数据返回,不然直接报错
五,process_view:
格式:process_view(self, request, view_func, view_args, view_kwargs)
request:request是HttpRequest对象。
view_func:view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args:view_args是将传递给视图的位置参数的列表.
view_kwargs:view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。
Django会在调用视图函数之前调用process_view方法。
ps:
它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器。
process_view方法是在Django路由系统之后,视图系统之前执行的,执行顺序按照MIDDLEWARE中的注册顺序从前到后顺序执行的。
六,process_exception:
格式:process_exception(self, request, exception)
request:一个HttpRequest对象
exception:一个exception是视图函数异常产生的Exception对象。
这个方法只有在视图函数中出现异常了才执行。
ps:
返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
七,process_template_response:
格式:process_template_response(self, request, response)
request:一个HttpRequest对象。
response:TemplateResponse对象(由视图函数或者中间件产生)。
ps:process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
view.py中:
def index(request): print("app01 中的 index视图") def render(): print("in index/render") return HttpResponse("O98K") rep = HttpResponse("OK") rep.render = render # 添加一个render属性时,触发process_template_response return rep