码迷,mamicode.com
首页 > 其他好文 > 详细

Django补充——中间件、请求的生命周期等

时间:2017-09-19 19:48:37      阅读:351      评论:0      收藏:0      [点我收藏+]

标签:inpu   字符串   init   3.2   rem   返回   方式   本质   gem   

一:中间件

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补充——中间件、请求的生命周期等

标签:inpu   字符串   init   3.2   rem   返回   方式   本质   gem   

原文地址:http://www.cnblogs.com/Vee-Wang/p/7553534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!