django中间件
-
django请求生命周期流程图
-
django中间件是django的门户
1.请求来的时候需要先经过中间件才能到达真正的django后端
2.响应走的时候最后也需要经过中间件才能发送出去 -
django自带七个中间件(研究django中间件代码规律)
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.middleware.security import SecurityMiddleware
# 引号内,是路径+类的形式
- 部分源码:
class SessionMiddleware(MiddlewareMixin):
def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
request.session = self.SessionStore(session_key)
def process_response(self, request, response):
return response
class CsrfViewMiddleware(MiddlewareMixin):
def process_request(self, request):
csrf_token = self._get_token(request)
if csrf_token is not None:
# Use same token next time.
request.META['CSRF_COOKIE'] = csrf_token
def process_view(self, request, callback, callback_args, callback_kwargs):
return self._accept(request)
def process_response(self, request, response):
return response
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
request.user = SimpleLazyObject(lambda: get_user(request))
- django支持程序员自定义中间件并且暴露给程序员五个可以自定义的方法
1.必须掌握
process_request
process_response
2.了解即可
process_view
process_template_response
process_exception
如何自定义中间件
- 在项目名或者应用名下创建一个任意名称的文件夹
- 在该文件夹内创建一个任意名称的py文件
- 在该py文件内需要书写类(这个类必须继承MiddlewareMixin) 然后在这个类里面就可以自定义五个方法了 (这五个方法并不是全部都需要书写,用几个写几个)
- 需要将类的路径以字符串的形式注册到配置文件中才能生效
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',
'你自己写的中间件的路径1',
'你自己写的中间件的路径2',
'你自己写的中间件的路径3',
]
1.必须掌握
process_request
1.请求来的时候需要经过每一个中间件里面的process_request方法
结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
2.如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件
3.如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行而是直接原路返回(校验失败不允许访问...),
process_request方法就是用来做全局相关的所有限制功能
process_response
1.响应走的时候需要结果每一个中间件里面的process_response方法,该方法有两个额外的参数request,response
2.该方法必须返回一个HttpResponse对象
1.默认返回的就是形参response
2.你也可以自己返回自己的
3.顺序是按照配置文件中注册了的中间件从下往上依次经过,如果你没有定义的话 直接跳过执行下一个
研究如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是经过所有的中间件里面的
process_response还是有其他情况
是其他情况:就是会直接走同级别的process_reponse返回
flask框架也有一个中间件但是它的规律
只要返回数据了就必须经过所有中间件里面的类似于process_reponse方法
settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
...
# 注册自己的中间件,尽量将自己定义的中间件放在最后(在应用下创建路径有提示,如果在项目下创建就没有提示了)
'app01.mymiddleware.mydd.MyMiddleware1',
'app01.mymiddleware.mydd.MyMiddleware2',
]
mydd.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddleware1(MiddlewareMixin):
def process_request(self, request):
print('我是第一个自定义中间件里面的process_request方法')
# return HttpResponse('baby!')
def process_response(self, request, response):
# response: 就是django后端返回给浏览器的内容
print('我是第一个自定义中间件里面的process_response方法')
# 方式一:
return response
# 方式二:
# return HttpResponse('hello world')
class MyMiddleware2(MiddlewareMixin):
def process_request(self, request):
print('我是第二个自定义中间件里面的process_request方法')
def process_response(self, request, response):
print('我是第二个自定义中间件里面的process_response方法')
return response
urls.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/',views.index),
]
views.py
from django.shortcuts import render, HttpResponse
def index(request):
print('我是视图函数index')
return HttpResponse('ok')
研究如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是经过所有的中间件里面的
process_response还是有其他情况
是其他情况:就是会直接走同级别的process_reponse返回
2.了解即可
process_view
路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该放法
顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
process_template_response
返回的HttpResponse对象有render属性的时候才会触发
顺序是按照配置文件中注册了的中间件从下往上依次经过
def index(request):
print('我是视图函数index')
obj = HttpResponse('index')
def render():
print('内部的render')
return HttpResponse('098k')
obj.render = render
return obj
process_exception
当视图函数中出现异常的情况下触发
顺序是按照配置文件中注册了的中间件从下往上依次经过
def index(request):
print(age) # age没有定义
print('我是视图函数index')
return HttpResponse('index')