Django補充——中間件、請求的生命周期等
一:中間件
django 中的中間件(middleware),在django中,中間件其實就是一個類,在請求到來和結束後,django會根據自己的規則在合適的時機執行中間件中相應的方法。
在django項目的settings模塊中,有一個 MIDDLEWARE_CLASSES 變量,其中每一個元素就是一個中間件,如下圖。
與mange.py在同一目錄下的文件夾 wupeiqi/middleware下的auth.py文件中的Authentication類
中間件中可以定義四個方法,分別是:
- process_request(self,request)
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse對象,如果是None,則繼續按照django定義的規則向下執行,如果是HttpResonse對象,則直接將該對象返回給用戶。
自定義中間件:
1、創建中間件類
class RequestExeute(object): def process_request(self,request): pass def process_view(self, request, callback, callback_args, callback_kwargs): i=1 pass def process_exception(self, request, exception): pass def process_response(self, request, response): return response
""" class M1(MiddlewareMixin): def process_request(self,request): print(‘m1.process_request‘) def process_view(self,request, view_func, view_func_args, view_func_kwargs): print(兩種方式‘m1.process_view‘) def process_exception(self,request,exception): print(‘m1.process_exception‘) def process_response(self,request,response): print(‘m1.process_response‘) return response def process_template_response(self,request,response): print(‘m1.process_template_response‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘) def process_view(self, request, view_func, view_func_args, view_func_kwargs): print(‘M2.process_view‘) def process_exception(self,request,exception): print(‘m2.process_exception‘) return HttpResponse(‘開發的程序員已經被打死‘) def process_response(self, request, response): print(‘m2.process_response‘) return response def process_template_response(self,request,response): print(‘m2.process_template_response‘) return response """ from django.shortcuts import HttpResponse,redirect 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 class M1(MiddlewareMixin): def process_response(self, request, response): print(‘m2.process_response‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘)
2、註冊中間件
MIDDLEWARE_CLASSES = ( ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, ‘django.middleware.csrf.CsrfViewMiddleware‘, ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.auth.middleware.SessionAuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ‘wupeiqi.middleware.auth.RequestExeute‘, #在合適的位置引入 ‘md.middleware.M1‘, ‘md.middleware.M2‘, )
二、 Http請求本質
Django程序:socket服務端
a. 服務端監聽IP和端口
c. 接受請求
\r\n\r\n:請求頭和請求體
\r\n
&
request.POST
request.GET
d. 響應:
響應頭: location:www.oldboyedu.com
響應體
e. 斷開連接
瀏覽器: socket客戶端
b. 瀏覽器發送:
GET請求:
"GET /index.html http1.1\r\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..\r\n\r\nAccept-Encoding:gzip\r\n\r\n"
POST請求:
"POST /index.html http1.1\r\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..\r\n\r\nAccept-Encoding:gzip\r\n\r\nuser=cqz&hobby=lihao"
e. 斷開連接
COOKIE: 請求頭和響應頭中存在
三、Django請求的生命周期
wsgi -> 中間件 -> 路由系統 -> 視圖函數(ORM,Template,渲染)
- wsgiref
- uwsgi
四、FBV和CBV
1、FBV
FBV(function base views) 就是在視圖裏使用函數處理請求。
看代碼:
urls.py
from django.conf.urls import url, include # from django.contrib import admin from mytest import views urlpatterns = [ # url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘, views.index), ]
views.py
from django.shortcuts import render def index(req): if req.method == ‘POST‘: print(‘method is :‘ + req.method) elif req.method == ‘GET‘: print(‘method is :‘ + req.method) return render(req, ‘index.html‘)
註意此處定義的是函數【def index(req):】
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <form action="" method="post"> <input type="text" name="A" /> <input type="submit" name="b" value="提交" /> </form> </body> </html>
2、CBV
CBV(class base views) 就是在視圖裏使用類處理請求。
將上述代碼中的urls.py 修改為如下:
from mytest import views urlpatterns = [ # url(r‘^index/‘, views.index), url(r‘^index/‘, views.Index.as_view()), ]
註:url(r‘^index/‘, views.Index.as_view()), 是固定用法。
將上述代碼中的views.py 修改為如下:
from django.views import View class Index(View): def get(self, req): print(‘method is :‘ + req.method) return render(req, ‘index.html‘) def post(self, req): print(‘method is :‘ + req.method) return render(req, ‘index.html‘)
3、裝飾器的使用
from django.utils.decorators import method_decorator
3.1 在get,post方法上
class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,‘login.html‘) @method_decorator(test) def post(self,request): # request.GET # request.POST # 請求頭中的:content-type # request.body user = request.POST.get(‘user‘) pwd = request.POST.get(‘pwd‘) if user == ‘alex‘ and pwd == "alex3714": # 生成隨機字符串 # 寫瀏覽器cookie: session_id: 隨機字符串 # 寫到服務端session: # { # "隨機字符串": {‘user_info‘:‘alex} # } request.session[‘user_info‘] = "alex" return redirect(‘/index.html‘) return render(request, ‘login.html‘)
3.2 在dispatch方法上
class LoginView(View): @method_decorator(test) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,‘login.html‘) def post(self,request): # request.GET # request.POST # 請求頭中的:content-type # request.body user = request.POST.get(‘user‘) pwd = request.POST.get(‘pwd‘) if user == ‘alex‘ and pwd == "alex3714": # 生成隨機字符串 # 寫瀏覽器cookie: session_id: 隨機字符串 # 寫到服務端session: # { # "隨機字符串": {‘user_info‘:‘alex} # } request.session[‘user_info‘] = "alex" return redirect(‘/index.html‘) return render(request, ‘login.html‘)View Code
3.3 在類上
@method_decorator(test,name=‘get‘) class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,‘login.html‘) def post(self,request): # request.GET # request.POST # 請求頭中的:content-type # request.body user = request.POST.get(‘user‘) pwd = request.POST.get(‘pwd‘) if user == ‘alex‘ and pwd == "alex3714": # 生成隨機字符串 # 寫瀏覽器cookie: session_id: 隨機字符串 # 寫到服務端session: # { # "隨機字符串": {‘user_info‘:‘alex} # } request.session[‘user_info‘] = "alex" return redirect(‘/index.html‘) return render(request, ‘login.html‘)
特殊:CSRF Token只能加到dispatch
from django.views.decorators.csrf import csrf_exempt,csrf_protect class LoginView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,‘login.html‘) def post(self,request): # request.GET # request.POST # 請求頭中的:content-type # request.body user = request.POST.get(‘user‘) pwd = request.POST.get(‘pwd‘) if user == ‘alex‘ and pwd == "alex3714": # 生成隨機字符串 # 寫瀏覽器cookie: session_id: 隨機字符串 # 寫到服務端session: # { # "隨機字符串": {‘user_info‘:‘alex} # } request.session[‘user_info‘] = "alex" return redirect(‘/index.html‘) return render(request, ‘login.html‘)View Code
Django補充——中間件、請求的生命周期等