1. 程式人生 > >Django補充——中間件、請求的生命周期等

Django補充——中間件、請求的生命周期等

文件中 ldb self tor accept .site 分享 body jpg

一:中間件

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補充——中間件、請求的生命周期等