只要是涉及到全局相关的功能都可以使用中间件方便的完成
"""
django中间件是django的门户1.请求来的时候需要经过中间件才能达到真正的django后端2.响应走的时候最后也需要经过中间件才能发送出去
"""
class SecurityMiddleware(MiddlewareMixin):def process_request(self, request):path = request.path.lstrip("/")if (self.redirectand not request.is_secure()and not any(pattern.search(path) for pattern in self.redirect_exempt)):host = self.redirect_host or request.get_host()return HttpResponsePermanentRedirect("https://%s%s" % (host, request.get_full_path()))def process_response(self, request, response):return responseclass AuthenticationMiddleware(MiddlewareMixin):def process_request(self, request):request.user = SimpleLazyObject(lambda: get_user(request))class CsrfViewMiddleware(MiddlewareMixin):def process_request(self, request):try:csrf_secret = self._get_secret(request)except InvalidTokenFormat:_add_new_csrf_cookie(request)else:if csrf_secret is not None:request.META["CSRF_COOKIE"] = csrf_secretdef process_view(self, request, callback, callback_args, callback_kwargs):return self._accept(request)def process_response(self, request, response):return response
"""django支持程序员自定义中间件,并且暴露给程序员五个可以自定义的方法1.必须了解process_requestprocess_response2.了解即可process_viewprocess_template_responseprocess_exception
"""
"""
1.在项目名或者应用下创建一个任意名称的文件夹,
2.在该文件夹下创建任意任意名字的py文件
3.在该py文件需要书写类,必须继承MiddlewareMixin然后就可以自定义五个方法(这五个方法用几个写几个,并不需要全都写)
4.需要将类的路径以字符串的形式注册到配置文件中才能生效
"""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','自己写的中间件路径','自己写的中间件路径','自己写的中间价路径',
]
启动项目,查看中间件是否生效
添加一个路由,写一个视图函数,查看执行顺序
from django.contrib import admin
from django.urls import path
from App import views
urlpatterns = [path('admin/', admin.site.urls),path('index/',views.index),
]
# Create your views here.
def index(request):print('我是视图函数index')return HttpResponse('index')
启动项目,浏览器输入路由
再写一个中间件,并颠倒注册顺序
添加返回值
总结:
请求来的时候是要经过每一个中间件里的process_request方法,结果的顺序按照配置文件中注册的中间件从上往下的顺序依次执行
如果中间件里面没有定义process_request方法,直接跳过,执行下一个
如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行,而是直接原路返回(校验失败,不允许访问)
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponseclass MyMiddleWare(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间件里面的process_request方法')def process_response(self, request, response):print('我是第一个自定义中间件里面的process_response方法')""":param request::param response: django后端返回给浏览器的内容:return:"""return responseclass MyMiddleWare2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间件里面的process_request方法')def process_response(self, request, response):print('我是第二个自定义中间件里面的process_response方法')return response
浏览器输入路由,回车
返回自己的HttpResponse对象
原本后端是要返回index
的,走到中间件里面,先经过MyMiddleWare
,返回index
,但是经过MyMiddleWare2
的时候来了一个偷天换日,把原本想要返回的响应换成自己的hello!
,之后所有的中间件拿到的全是自己写的返回响应的内容
总结:
响应走的时候需要经过每一个中间件里的process_response方法,该方法有两个额外的参数(request,response)
该方法必须返回一个HttpResponse对象
顺序是按照配置文件中注册了的中间件从下往上依次经过,如果没有定义,直接执行上一个
如果在先注册了的中间件中的process_request方法就已经返回了HttpResponse对象,那么响应走的时候经过所有的中间件里面的process_response是否有其他情况?
观察上图得出以下结论:
首先请求来的时候,会依次经过每一个注册了的中间件里的process_reques
t方法,一旦process_request
方法返回了一个HttpResponse
对象,那么会直接不再往下走,而是直接经过同级别的process_response
往外走。
def process_view(self, request, view_name, *args, **kwargs):print(view_name, args, kwargs)print('我是第一个自定义中间件里的process_view')
特点:
路由匹配成功之后,执行视图函数之前,会自动执行中间件里面的process_view方法,顺序按照配置文件中注册的中间件从上往下的顺序依次执行
def process_response(self, request, response):print('我是第二个自定义中间件里面的process_response方法')return response
# views.pydef index(request):print('我是视图函数index')obj = HttpResponse('index')def render():print('内部的render')return HttpResponse('98K')obj.render = renderreturn obj
返回的HttpResponse对象有render属性的时候,才会触发,顺序是
按照配置文件中注册的中间件从下往上依次经过
def process_exception(self, request, exception):print(exception)print('我是第二个自定义中间件里的process_exception')
当视图函数中出现异常的情况下,触发。
顺序是按照配置文件中注册的中间件从下往上依次经过
全部代码:
# -*- coding: UTF-8 -*-
# @Date :2022/11/9 19:03
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponseclass MyMiddleWare(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间件里面的process_request方法')def process_response(self, request, response):print('我是第一个自定义中间件里面的process_response方法')""":param request::param response: django后端返回给浏览器的内容:return:"""return responsedef process_view(self, request, view_name, *args, **kwargs):print(view_name, args, kwargs)print('我是第一个自定义中间件里的process_view')def process_template_response(self, resquest, response):print('我是第一个自定义中间件里的process_template_response')return responsedef process_exception(self, request, exception):print(exception)print('我是第一个自定义中间件里的process_exception')class MyMiddleWare2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间件里面的process_request方法')# return HttpResponse('JayChou')def process_response(self, request, response):print('我是第二个自定义中间件里面的process_response方法')return response# return HttpResponse('hello !')def process_view(self, request, view_name, *args, **kwargs):print(view_name, args, kwargs)print('我是第二个自定义中间件里的process_view')def process_template_response(self, resquest, response):print('我是第二个自定义中间件里的process_template_response')return responsedef process_exception(self, request, exception):print(exception)print('我是第二个自定义中间件里的process_exception')