django:
- 中間件
- csrf
- 緩存
- 信号
一 、 中間件
Django的基本生命周期:
使用者發起一次請求到url,再轉發給視圖函數,視圖函數把資料取出來再把模闆拿出來,最後進行渲染傳回給使用者

Django帶有中間件的生命周期:
中間件比作是橫者的管
請求來的是後先通過中間件,再到路由比對映射到view視圖裡,在view視圖裡的邏輯執行完了後再通過中間件傳回給使用者
每個中間件都必須繼承這個類 MiddlewareMixin
class MiddlewareMixin(object): #中間件必須繼承這個類
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
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',
"md.hxl.HXL", #自己寫的中間件
"md.hxl.GYC", #自己定制的中間件
]
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class LBS(MiddlewareMixin):
def process_request(self,request):
print("lbs-->process_request")
#return HttpResponse("403。。。") #如果在這裡加上return那麼将不會走到views和其他中間件,從走過的中間件的process_response傳回
def process_response(self,request,response):
print("lbs-->process_response")
return response
class HXL(MiddlewareMixin):
def process_request(self,request):
print("HXL-->process_request")
def process_response(self,request,response):
print("HXL-->process_response")
return response
class GYC(MiddlewareMixin):
def process_request(self,request):
print("gyc-->process_request")
def process_response(self,request,response):#必須有三個參數
"""
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("gyc-->process_response")
return response
#執行的順序
#HXL-->process_request
#gyc-->process_request
#views
#gyc-->process_response
#HXL-->process_response
#直接return的順序
#lbs-->process_request
#lbs-->process_response
如果 process_request 函數有傳回值的話就不再走其他中間件,就像csrf一樣。
優化版
自定制中間件需要繼承的類
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddlewareMixin(object):#自己寫一個中間件繼承的類
def __init__(self, get_response=None):
self.get_response = get_response
super(MyMiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
#執行目前中間件的process_request
response = self.process_request(request)
if not response:
#執行下一個中間件的__call__
response = self.get_response(request)
if hasattr(self, 'process_response'):
#執行目前中間件的process_response
response = self.process_response(request, response)
return response
class LBS(MyMiddlewareMixin):
def process_request(self,request):
print("lbs-->process_request")
return HttpResponse("403。。。") #如果在這裡加上return那麼将不會走到views和其他中間件,從走過的中間件的process_response傳回
def process_response(self,request,response):
print("lbs-->process_response")
return response
class HXL(MyMiddlewareMixin):
def process_request(self,request):
print("HXL-->process_request")
def process_response(self,request,response):
print("HXL-->process_response")
return response
class GYC(MyMiddlewareMixin):
def process_request(self,request):
print("gyc-->process_request")
def process_response(self,request,response):#必須有三個參數
"""
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("gyc-->process_response")
return response
中間件優化版
process_view(self, request, views, views_args, views_kwargs):
process_exception(self, request, exception):
process_exception隻對views函數有效 ,對process_vie無效
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MyMiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
#執行目前中間件的process_request
response = self.process_request(request)
if not response:
#執行下一個中間件的__call__
response = self.get_response(request)
if hasattr(self, 'process_response'):
#執行目前中間件的process_response
response = self.process_response(request, response)
return response
class LBS(MyMiddlewareMixin):
def process_request(self,request):
"""
在使用者請求時執行的函數,拿到請求
:param request:
:return:
"""
print("lbs-->process_request")
# return HttpResponse("403。。。") #如果在這裡加上return那麼将不會走到views和其他中間件,從走過的中間件的process_response傳回
def process_view(self, request, views_func, views_args, views_kwargs):
"""
在執行views之前調用的函數,擷取路由上的參數
:param request:
:param views_func:對應的就是views的視圖函數
:param views_args:參數清單
:param views_kwargs:關鍵字參數
:return:
"""
print("lbs-->process_view")
print(views_func, views_args, views_kwargs)
def process_response(self,request,response):
"""
在傳回資料時執行的函數,拿到傳回的資料
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("lbs-->process_response")
return response
def process_exception(self, request, exception):
"""
在異常觸發時執行的函數,拿到異常資訊
報錯以後調用的函數,如果沒處理則到下一個異常函數處理,都沒處理則抛異常
:param request:
:param exception:異常資訊
:return 如果return了就不往下走,傳回值傳回給使用者
"""
print("lbs-->process_exception",exception)
class HXL(MyMiddlewareMixin):
def process_request(self,request):
print("HXL-->process_request")
def process_view(self, request, views, views_args, views_kwargs):
print("HXL-->process_view")
def process_response(self,request,response):
print("HXL-->process_response")
return response
def process_exception(self, request, exception):
print("HXL-->process_exception")
class GYC(MyMiddlewareMixin):
def process_request(self,request):
print("gyc-->process_request")
def process_view(self, request, views, views_args, views_kwargs):
print("gyc-->process_view")
def process_response(self,request,response):#必須有三個參數
"""
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("gyc-->process_response")
return response
def process_exception(self, request, exception):
print("gyc-->process_exception")
View Code
process_template_response(self,request,response)
from django.shortcuts import render,HttpResponse
# Create your views here.
class Foo:
def __init__(self,request,html):
self.req=request
self.html=html
def render(self):
return render(self.req,self.html)
def test(request,nid):
print("views")
return Foo(request,"abc.html")
傳回的對象裡有render的是後執行
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MyMiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
#執行目前中間件的process_request
response = self.process_request(request)
if not response:
#執行下一個中間件的__call__
response = self.get_response(request)
if hasattr(self, 'process_response'):
#執行目前中間件的process_response
response = self.process_response(request, response)
return response
class LBS(MyMiddlewareMixin):
def process_request(self,request):
"""
在使用者請求時執行的函數,拿到請求
:param request:
:return:
"""
print("lbs-->process_request")
# return HttpResponse("403。。。") #如果在這裡加上return那麼将不會走到views和其他中間件,從走過的中間件的process_response傳回
def process_view(self, request, views_func, views_args, views_kwargs):
"""
在執行views之前調用的函數,擷取路由上的參數
:param request:
:param views_func:對應的就是views的視圖函數
:param views_args:參數清單
:param views_kwargs:關鍵字參數
:return:
"""
print("lbs-->process_view")
print(views_func, views_args, views_kwargs)
def process_response(self,request,response):
"""
在傳回資料時執行的函數,拿到傳回的資料
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("lbs-->process_response")
return response
def process_exception(self, request, exception):
"""
在異常觸發時執行的函數,拿到異常資訊
報錯以後調用的函數,如果沒處理則到下一個異常函數處理,都沒處理則抛異常
:param request:
:param exception:異常資訊
:return 如果return了就不往下走,傳回值傳回給使用者
"""
print("lbs-->process_exception",exception)
def process_template_response(self,request,response):
"""
傳回的對象如果有render方法那麼就會執行
:param request:請求資訊
:param response:傳回的對象
:return:
"""
print("lbs-->process_template_response")
return response
class HXL(MyMiddlewareMixin):
def process_request(self,request):
print("HXL-->process_request")
def process_view(self, request, views, views_args, views_kwargs):
print("HXL-->process_view")
def process_response(self,request,response):
print("HXL-->process_response")
return response
def process_exception(self, request, exception):
print("HXL-->process_exception")
def process_template_response(self,request,response):
print("HXL-->process_template_response")
return response
class GYC(MyMiddlewareMixin):
def process_request(self,request):
print("gyc-->process_request")
def process_view(self, request, views, views_args, views_kwargs):
print("gyc-->process_view")
def process_response(self,request,response):#必須有三個參數
"""
:param request:
:param response: views傳回的資料
:return: 必須傳回response
"""
print("gyc-->process_response")
return response
def process_exception(self, request, exception):
print("gyc-->process_exception")
def process_template_response(self,request,response):
print("gyc-->process_template_response")
return response
process_template_response
中間件中可以定義四個方法,分别是:
- process_request(self,request) #在請求到了之前就已經執行了,比如csrf,請求頭的過濾
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_template_response(self,request,response) #在views結束後時執行的
- process_exception(self, request, exception)
- process_response(self, request, response)