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. 接受请求
       :请求头和请求体
      
      &
      request.POST
      request.GET
    d. 响应:
      响应头: location:www.oldboyedu.com
      响应体
    e. 断开连接

  浏览器: socket客户端

    b. 浏览器发送:
      GET请求:
        "GET /index.html http1.1 User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6.. Accept-Encoding:gzip "
      POST请求:
        "POST /index.html http1.1 User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6.. Accept-Encoding:gzip user=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
原文地址:https://www.cnblogs.com/Vee-Wang/p/7553534.html