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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM