zoukankan      html  css  js  c++  java
  • Django之中间件

    一.CBV加装饰器

      第一种  @method_decorator(装饰器)  加在get上
    
      第二种  @method_decorator(login_auth,name='get')  加在类上
    
      第三种  @method_decorator(login_auth)  加在dispatch上  3.7版本要return super().dispatch
    from django.utils.decorators import method_decorator
    
    
    @method_decorator(login_auth,name='get')    #第二种  name参数必须指定
    class MyHome(View):
        @method_decorator(login_auth)    #第三种  get和post都会被装饰
        def dispatch(self,request,*args,**kwargs):
            super().dispatch(request,*args,**kwargs)
        
        @method_decorator(login_auth)  #第一种
        def get(self,request):
            return HttpResponse('get')
        
        def post(self,request):
            return HttpResponse('post')

    二.中间件:

          1. 首先,什么是中间件?

    django请求生命周期完整版,中间件类似于django的门卫,数据在进入和离开时都需要经过中间件

         2. 中间件能干嘛?

    控制用户访问频率,全局登陆校验,用户访问白名单,黑名单等

         3. Django默认有七个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法

    中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
    有response需要加上return
    
    process_request(self,request) process_view(self, request, view_func, view_args, view_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response)

      首先查看settings.py中的七个中间件,然后仿照继承中间件的一个类,从而自定义两个中间件,新创建一个文件夹和文件:

    from django.utils.deprecation import MiddlewareMixin
    
    
    
    class MyMiddleWare(MiddlewareMixin):
        def process_request(self,request):
            print('我是第一个自定义的中间件中process_request方法')
    
    
        def process_response(self,request,response):
            print('我是第一个自定义的中间件中process_response方法')
            return response
    class MyMiddleWare1(MiddlewareMixin):
        def process_request(self,request):
            print('我是第二个自定义的中间件中process_request方法')
    
    
        def process_response(self,request,response):
            print('我是第二个自定义的中间件中process_response方法')
            return response

       然后把路径添加在中间件目录的后面:

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'mymiddleware.middleware.MyMiddleWare',
        'mymiddleware.middleware.MyMiddleWare1'
    ]

    视图函数:

    def index(request):
        print('我是视图函数')
        return HttpResponse('我是视图函数')

    执行顺序:

    我是第一个自定义的中间件中process_request方法
    我是第二个自定义的中间件中process_request方法
    我是视图函数
    我是第二个自定义的中间件中process_response方法
    我是第一个自定义的中间件中process_response方法

    如果process_request返回值是None,程序会继续执行,如果是一个HttpResponse对象(三剑客),程序会在同级掉头,

    不会走下一个中间件,更不会走视图函数:

    class MyMiddleWare(MiddlewareMixin):
        def process_request(self,request):
            print('我是第一个自定义的中间件中process_request方法')
            return HttpResponse('我是第一个中间件里面返回的对象')
           # return render(request, 'index.html')  同理

    执行到这个中间件就回头了:

    我是第一个自定义的中间件中process_request方法
    我是第一个自定义的中间件中process_response方法

    process_view方法:路由匹配成功执行视图函数之前会走这个方法

        def process_view(self, request, view_func, view_args, view_kwargs):
            print('我是第一个自定义的中间件中process_view方法')
            print(view_func.__name__)

     执行顺序:

    我是第一个自定义的中间件中process_request方法
    我是第二个自定义的中间件中process_request方法
    我是第一个自定义的中间件中process_view方法
    index
    我是第二个自定义的中间件中process_view方法
    index
    我是视图函数
    我是第二个自定义的中间件中process_response方法
    我是第一个自定义的中间件中process_response方法
    process_exception方法:异常捕获,顺序从下往上
        def process_exception(self, request, exception):
            print("我是第一个自定义的中间件中process_exception方法",exception)
    process_template_response方法:顺序也是从下往上
    def process_template_response(self, request, response):
    print('我是第一个自定义的中间件中process_template_response方法')
    return response

         看效果要用这个视图函数:

    def index(request):
        print("app01 中的 index视图")
        def render():
            print("in index/render")
            return HttpResponse("O98K")
        rep = HttpResponse("OK")
        rep.render = render
        return rep

     流程图:

     如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。

    假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。

    process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。总结所有的执行流程如下:

    中间件版登陆验证:
    urls.py
    
    from app02 import views as v2
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/',v2.login),
        url(r'^home/',v2.home),
        url(r'^index/',v2.index)
    ]
    ----------------------------------------------------------------------------
    views.py
    
    from django.shortcuts import render,redirect,HttpResponse
    from app02 import models
    # Create your views here.
    def login(request):
        error_msg=''
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            user_obj=models.User.objects.filter(username=username,password=password)
            if  user_obj:
                #设置session
                request.session['login']='ok'
                #获取用户想直接访问的URL
                url=request.GET.get('next')
                #如果有,就跳转到客户初始想访问的URL
                if not url:
                    #没有则默认跳转到home页面
                    url='/home/'
                return redirect(url)
            else:
                error_msg='username or password error!'
        return render(request,'login.html',{'error_msg':error_msg})
    
    def home(request):
        return HttpResponse('<h1>这是home页面 只有登录了才能看到</h1>')
    
    def index(request):
        return HttpResponse('<h1>这是index页面 也只有登录了才能看到<h1>')
    ----------------------------------------------------------------------------
    login.html
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登陆页面</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        <label for="">username:<input type="text" name="username"></label>
        <label for="">password:<input type="password" name="password"></label>
        <input type="submit" value="submit">
    </form>
    <h1 style="color: red">{{ error_msg }}</h1>
    
    </body>
    </html>
    
    ----------------------------------------------------------------------------
    middlewares.py
    
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import redirect
    
    class Check_Login(MiddlewareMixin):
        def process_request(self,request):
            next_url=request.path_info
            if not next_url.startswith('/login/'):
                is_login=request.session.get('login','')
                if not is_login:
                    return redirect('/login/?next={}'.format(next_url))
    
    
    ----------------------------------------------------------------------------
    在settings.py中注册
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'middleware.my_middleware.Check_Login',
    
    ]
    
    

    Django请求流程图:

     
  • 相关阅读:
    《Selenium自动化测试实战》新书上市,有需要朋友们可以了解下,欢迎大家多提宝贵意见
    OrchardCore 如何动态加载模块?
    性能测试基础知识体系
    职场新人如何快速融入团队
    技术之外的工程师另类成长指南
    4.17-线上-技术沙龙问题汇总答疑
    3.20-上海-技术沙龙问题汇总答疑
    推荐书单4.0:测试工程师破局之路
    从技术专家到技术管理,我对管理的思考
    chrome打开本地链接
  • 原文地址:https://www.cnblogs.com/sima-3/p/11060025.html
Copyright © 2011-2022 走看看