zoukankan      html  css  js  c++  java
  • django组件:中间件

    全局性的逻辑处理

    一、中间件的概念

    中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎使用,用不好会影响到性能。
    Django的中间件的定义:

    Middleware is a framework of hooks into Django’s request/response processing. <br>It’s a light, low-level “plugin” system for globally altering Django’s input or output.

    如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。
    可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

    setting.py

    Django 默认的Middleware:默认定义7个

    一个中间件就是一个类

    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',
    ]

    中间件起到什么角色,一个完整django经历那些阶段

    自定义中间件

    中间件中一共有四个方法:
    
    process_request
    process_view
    process_exception
    process_response

    process_request,process_response

    当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

    上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin
    需要导入

    from django.utils.deprecation import MiddlewareMixin

    无论访问的路径是什么,中间件都会执行

    url

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index),
        path('index_new/', views.index_new),
    ]

    views.py

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    def index(request):
        return HttpResponse('index')
    
    def index_new(request):
        return HttpResponse('is new index')

    自定义中间件

    my_middlewares.py

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class CustomerMiddleware(MiddlewareMixin):
        def process_request(self,request):
            print("CustomerMiddleware1 process_request....")
            #return HttpResponse("forbidden....")
    
        def process_response(self,request,response):
            print("CustomerMiddleware1 process_response")
    
            return response
            #return HttpResponse("hello yuan")
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print("CustomerMiddleware1 process_view")
    
        def process_exception(self, request, exception):
    
            print("CustomerMiddleware1 process_exception")
            return HttpResponse(exception)
    
    class CustomerMiddleware2(MiddlewareMixin):
    
        def process_request(self,request):
            print("CustomerMiddleware2 process_request....")
    
        def process_response(self,request,response):
            print("CustomerMiddleware2 process_response")
            return response
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # print("====>",callback(callback_args))
            print("CustomerMiddleware2 process_view")
            # ret=callback(callback_args)
            # return ret
    
        def process_exception(self, request, exception):
    
            print("CustomerMiddleware2 process_exception")
    
            #return HttpResponse(exception)

    在settings配置

    分别访问index index_new

    中间件都会执行

    CustomerMiddleware1 process_request....
    CustomerMiddleware2 process_request....
    CustomerMiddleware1 process_view
    CustomerMiddleware2 process_view
    CustomerMiddleware2 process_response
    CustomerMiddleware1 process_response

     在view.py

    def index(request):
        print('-----index-----')
        return HttpResponse('index')

    在浏览器中访问index

    CustomerMiddleware1 process_request....
    CustomerMiddleware2 process_request....
    CustomerMiddleware1 process_view
    CustomerMiddleware2 process_view
    -----index-----  # view.py视图
    CustomerMiddleware2 process_response
    CustomerMiddleware1 process_response
    先请求--视图--响应

    具体分析:

    1、当自定义的中间件中只有请求和相应 ,:

     def process_request(self,request):
            print("CustomerMiddleware1 process_request....")
            #return HttpResponse("forbidden....")
    
        def process_response(self,request,response):
            print("CustomerMiddleware1 process_response")
    
    
    
    
    

     2、当自定义的中间件有process_view

    
    
    class CustomerMiddleware(MiddlewareMixin):

    def process_request(self,request):
    print("CustomerMiddleware1 process_request....")

    #return HttpResponse("forbidden....")


    def process_response(self,request,response):
    print("CustomerMiddleware1 process_response")

    return response
    #return HttpResponse("hello yuan")

    def process_view(self, request, callback, callback_args, callback_kwargs):
    print("CustomerMiddleware1 process_view")


    结果如下:

    
    
    
    
    


    注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。

      3、当自定义的中间件有process_view 且 当views出现错误时:

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    
    class CustomerMiddleware(MiddlewareMixin):
    
        def process_request(self,request):
            print("CustomerMiddleware1 process_request....")
    
            #return HttpResponse("forbidden....")
    
    
        def process_response(self,request,response):
            print("CustomerMiddleware1 process_response")
    
            return response
            #return HttpResponse("hello yuan")
    #
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print("CustomerMiddleware1 process_view")
    # #
    #
        def process_exception(self, request, exception):
    
            print("CustomerMiddleware1 process_exception")
            return HttpResponse(exception)

     只需要掌握两个

    request

    response

     def process_request(self,request):
            print("CustomerMiddleware1 process_request....")
    
        
        def process_response(self,request,response):
            print("CustomerMiddleware1 process_response")
    
            return response #必须有返回值

    中间件应用之用户认证

    通过中间件实现装饰器 @login_required  用户认证

    完整代码实现

    url

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
        path('logout/', views.logout),
        path('reg/', views.reg),
        # path('set_pwd/', views.set_pwd),
        path('order/', views.order),
    ]

    views

    from django.shortcuts import render,redirect
    
    # Create your views here.
    from django.contrib import auth
    from django.contrib.auth.models import User
    from django.contrib.auth.decorators import login_required
    
    def login(request):
        if request.method=='POST':
            name=request.POST.get('user')
            pwd=request.POST.get('pwd')
            # 如果验证成功返回user对象,否则返回none
            user=auth.authenticate(username=name,password=pwd)
            print('user',user)
            if user:
                auth.login(request,user)  # request.user:当前登录对象
                # return redirect('/index/')
                # 加装饰器
    
                next_url = request.GET.get("next", "/index/")
                return redirect(next_url)
        return render(request,'login.html')
    
    #@login_required
    def index(request):
        # print('request.user',request.user)
        # if not request.user.is_authenticated:
        #     return redirect('/login/')
        # username=request.user
        return render(request,'index.html',locals())
    
    # 注销
    def logout(request):
        auth.logout(request)
        return redirect("/login/")
    
    # 注册
    def reg(request):
        if request.method == "POST":
            name = request.POST.get("user")
            pwd = request.POST.get("pwd")
            # User.objects.create(username=user,password=pwd)
            user = User.objects.create_user(username=name, password=pwd)
            return redirect("/login/")
        return render(request, "reg.html")
    
    #@login_required
    # 加装饰器后必须登录才能访问,为登录跳转到默认的页面
    def order(request):
    
        # if not request.user.is_authenticated:
        #     return redirect("/login/")
    
        return render(request,"order.html")

    settings.py

    
    
    STATIC_URL = '/static/'

    LOGIN_URL='/login/'

    #
    设置白名单 WHITE_LIST = ["/login/", "/reg/", "/logout/"]

    my_middlewares.py

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import redirect
    from authDemo import settings
    
    class AuthMiddleware(MiddlewareMixin):
    
        def process_request(self,request):
            white_list = settings.WHITE_LIST
            if request.path in white_list:
                return None
            if not request.user.is_authenticated:
                return redirect("/login/")

     设置成白名单的才可以访问,其他的不能访问;当用户登陆成功后,其他的视图就可以直接

    访问无需登录验证

    装饰器,中间件具体情况具体分析

    只有几个需要验证则装饰器

    需要大量验证的则中间件

    三、应用案例

    1、做IP访问频率限制

    某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。

    2、URL访问过滤

    如果用户访问的是login视图(放过)
    如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!
    作为延伸扩展内容,有余力的同学可以尝试着读一下以下两个自带的中间件:

    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
  • 相关阅读:
    高级(线性)素数筛
    Dijkstra(迪杰斯特拉)算法
    简单素数筛
    【解题报告】 POJ1958 奇怪的汉诺塔(Strange Tower of Hanoi)
    4 jQuery Chatting Plugins | jQuery UI Chatbox Plugin Examples Like Facebook, Gmail
    Web User Control Collection data is not storing
    How to turn on IE9 Compatibility View programmatically in Javascript
    从Javascrip 脚本中执行.exe 文件
    HtmlEditorExtender Ajax
    GRIDVIEW模板中查找控件的方式JAVASCRIPT
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9981896.html
Copyright © 2011-2022 走看看