Django中间件
Django中间件
只要是涉及到全局相关的功能都可以使用中间件方便的完成
- 全局用户身份校验
- 全局用户权限校验
- 全局访问频率校验
"""
django中间件是django的门户
1.请求来的时候需要经过中间件才能达到真正的django后端
2.响应走的时候最后也需要经过中间件才能发送出去
"""
1、默认中间件源码分析
class SecurityMiddleware(MiddlewareMixin):
def process_request(self, request):
path = request.path.lstrip("/")
if (
self.redirect
and 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 response
class 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_secret
def process_view(self, request, callback, callback_args, callback_kwargs):
return self._accept(request)
def process_response(self, request, response):
return response
"""
django支持程序员自定义中间件,并且暴露给程序员五个可以自定义的方法
1.必须了解
process_request
process_response
2.了解即可
process_view
process_template_response
process_exception
"""
2、自定义中间件
"""
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',
'自己写的中间件路径',
'自己写的中间件路径',
'自己写的中间价路径',
]
process_request(掌握)
![image-20221109191456363](https://img2023.cnblogs.com/blog/2034842/202212/2034842-20221212165504316-827736994.png)
启动项目,查看中间件是否生效
![image-20221109191548177](https://img2023.cnblogs.com/blog/2034842/202212/2034842-20221212165504964-627571165.png)
添加一个路由,写一个视图函数,查看执行顺序
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')
启动项目,浏览器输入路由
![image-20221109192047022](https://img2023.cnblogs.com/blog/2034842/202212/2034842-20221212165504875-1896634568.png)
再写一个中间件,并颠倒注册顺序
![image-20221109192636506](https://img2023.cnblogs.com/blog/2034842/202212/2034842-20221212165504709-68931503.png)
添加返回值
![image-20221109194306420](https://img2023.cnblogs.com/blog/2034842/202212/2034842-20221212165504623-64507303.png)
总结:
-
请求来的时候是要经过每一个中间件里的
process_request
方法,结果的顺序按照配置文件中注册的中间件从上往下的顺序依次执行 -
如果中间件里面没有定义
process_request
方法,直接跳过,执行下一个 -
如果该方法返回了
HttpResponse
对象,那么请求将不再继续往后执行,而是直接原路返回(校验失败,不允许访问)- 所以process_request方法就是用来做全局相关的所有限制功能
process_response(掌握)
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class 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 response
class 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对象
- 默认返回的就是形参response,
- 也可以自己返回自己的HttpResponse对象
-
顺序是按照配置文件中注册了的中间件从下往上依次经过,如果没有定义,直接执行上一个
如果在先注册了的中间件中的process_request方法就已经返回了HttpResponse对象,那么响应走的时候经过所有的中间件里面的process_response是否有其他情况?
观察上图得出以下结论:
首先请求来的时候,会依次经过每一个注册了的中间件里的process_reques
t方法,一旦process_request
方法返回了一个HttpResponse
对象,那么会直接不再往下走,而是直接经过同级别的process_response
往外走。
process_view(了解)
def process_view(self, request, view_name, *args, **kwargs):
print(view_name, args, kwargs)
print('我是第一个自定义中间件里的process_view')
特点:
路由匹配成功之后,执行视图函数之前,会自动执行中间件里面的process_view方法,顺序按照配置文件中注册的中间件从上往下的顺序依次执行
process_template_response(了解)
def process_response(self, request, response):
print('我是第二个自定义中间件里面的process_response方法')
return response
# views.py
def index(request):
print('我是视图函数index')
obj = HttpResponse('index')
def render():
print('内部的render')
return HttpResponse('98K')
obj.render = render
return obj
返回的HttpResponse对象有render属性的时候,才会触发,顺序是
按照配置文件中注册的中间件从下往上依次经过
process_execption(了解)
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 HttpResponse
class 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 response
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 response
def 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 response
def process_exception(self, request, exception):
print(exception)
print('我是第二个自定义中间件里的process_exception')
本文来自博客园,作者:ExpiredSaury,转载请注明原文链接:https://www.cnblogs.com/saury/p/16976531.html