• 144.中间件的原理和定义方式详解


    中间件

    中间件是在request和response处理过程中的一个插件。比如request到达视图四千,我们可以定义中间件来做一些相关的事情,比如可以判断这个用户有没有登录,如果登录了,就绑定一个对象到request上,也可以在response到达浏览器之前,做一些相关的处理,比如想要统一在response上设置一些cookie信息等。

    自定义中间件

    中间件所处的位置没有规定,只要是放到项目中即可,一般可以分为两种情况,如果中间件是属于某个app的,那么就可以在这个app下面创建一个python文件用来存储这个中间件,也可以专门创建一个python包,用来存放本项目的所有中间件。创建中间件有两种方式,一种是使用函数,一种是使用类。

    1.定义中间件函数

    (1)在APP中创建一个python文件,定义与该APP相关的中间件。如果我们想要自己定义的中间件,被django在执行操作的时候使用的话,就要在项目的settings.py文件中的MIDDLEWARE中添加appname.pythonfilename.functionname。函数定义示例代码如下:
    from .models import User
    
    def front_user_middlewares(get_response):
        print('front_user_middleware初始化执行的代码....')
        
        def middleware(request):
            print('request到达view视图之前执行的代码....')
            <!--1.在request到达view视图之前,对用户是否进行登录进行判断,如果登录了就在request上绑定一个对象front_user-->
            <!-因为python是一个动态执行的语言,即使在对象已经创建完成,也可以对对象随时绑定属性。-->
            
            <!--首先通过session中是否含有一个sessionid,如果有的话,就认为,该用户已经登录了。-->
            user_id = request.session.get('user_id')
            <!--判断如果user_id存在将执行什么操作,但是这种情况下,同时也存在着user_id不存在的情况,所以我们可以通过try...except...来实现。-->
            if user_id:
                try:
                    front_user = User.objects.get(pk=user_id)
                    request.front_user = front_user
                    print(request.front_user.username)
                except:
                    request.front_user = None
            request.front_user = None
            
            <!--执行get_response(request),就相当于转去执行视图函数了,这一点可以通过在相应的视图函数:print(”这是视图函数中执行的代码“),进行验证-->
            response = get_response(request)
            print('response到达浏览器之前执行的代码....')
            
            return response
            
        return middleware
    
    在middleware()函数之前的代码是运行该项目之后就会加载的,而middleware()函数中的代码是只有访问网站的时候才会执行的。
    (2)之后我们就可以在视图函数中直接使用request上的front_user对象了,示例代码如下:
    
    def index(request):
        print("这是index view中的代码")
        if request.front_user:
            print(request.front_user.username)
        return render(request, 'index.html')
    
    
    def my_list(request):
        print('这是my_list中的代码')
        if request.front_user:
            print(request.front_user.username)
        return HttpResponse('success!')
    

    2.定义中间件的类

    (1)要想让我们定义的中间件的类起作用的话,同样也需要在settings.py中的MIDDLEWARE中添加appname.pythonfilename.classname。比如,我们想要在request达到view视图函数之前判断用户是否登录,若登录了,就在request上绑定一个front_user对象并且该对象就是新登录的用户。若没有登录,同样为request绑定一个front_user对象,此时就设置为None。示例代码如下:
    # 2. 定义一个类
    from .models import User
    
    class FrontUserMiddleware(object):
    
        def __init__(self, get_response):
            print('front_user_middleware初始化执行的代码....')
            <!--需要先保存get_response,以后会用到-->
            self.get_response = get_response
    
        def __call__(self, request):
            print('request到达view之前执行的代码....')
            user_id = request.session.get('user_id')
            if user_id:
                try:
                    front_user = User.objects.get(pk=user_id)
                    request.front_user = front_user
                    print(request.front_user.username)
                except:
                    request.front_user = None
            request.front_user = None
            
            <!--执行get_response()函数就会转去执行view视图函数-->
            response = self.get_resonse(request)
            print('response到达浏览器之前执行的代码....')
            return response
    

    3.即将被遗弃的中间件的定义方式,示例代码如下:

    from django.utils.deprecation import MiddlewareMixin
    from .models import User
    
    
    class FrontUserMiddlewareMixin(MiddlewareMixin):
    
        def __init__(self, get_response):
            self.get_response = get_response
            print('front_user_middleware进行初始化执行的代码....')
    
        # 1. 定义request到达view视图之前执行的操作
        def process_request(self, request):
            print("request到达view视图之前执行的操作...")
            user_id = request.session.get('user_id')
            if user_id:
                try:
                    front_user = User.objects.get(pk=user_id)
                    request.front_user = front_user
                    print(request.front_user.username)
                except:
                    request.front_user = None
    
            request.front_user = None
    
    
        # 2. 定义response到达浏览器之前执行的操作
        def process_response(self, request, response):
            print('response到达浏览器之前执行的操作...')
            return response
    
    始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。
  • 相关阅读:
    IE input X 去掉文本框的叉叉和密码输入框的眼睛图标
    vue监听滚动事件 实现某元素吸顶或者固定位置显示
    判断滚动条到底部的JS逻辑
    vue plugin 插件编写以loading为例
    Maven使用yuicompressor-maven-plugin打包压缩css、js文件
    AngularJS 用 Interceptors 来统一处理 HTTP 请求和响应
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
    angular内ng存在属性是专门用来解决跨域问题的,$sce
    dede上怎么让所有链接在新窗口打开
    dede文章页调用当前栏目链接方法
  • 原文地址:https://www.cnblogs.com/guyan-2020/p/12354711.html
Copyright © 2020-2023  润新知