• Django中间件


    中间件是 Django 用来处理请求和响应的钩子框架。它是一个轻量级的、底层级的“插件”系统,用于全局性地控制Django 的输入或输出,可以理解为一些关卡。
    中间件可以放在你的工程的任何地方,并以Python路径的方式进行访问。
    可以把中间件比喻成洋葱,每一层代表一个中间件,每个请求从进入django到响应返回,django都可以通过中间件进行一定的操作。

    启用中间件

    在settings.py中,MIDDLEWARE列表表示要启用的中间件。

    
    MIDDLEWARE = [
        # 安全中间件
        'django.middleware.security.SecurityMiddleware',
        # 会话中间件,启用时支持session
        'django.contrib.sessions.middleware.SessionMiddleware',
        # “通用”中间件
        'django.middleware.common.CommonMiddleware',
        # CSRF 保护中间件
        'django.middleware.csrf.CsrfViewMiddleware',
        # 验证中间件
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        # 消息中间件
        'django.contrib.messages.middleware.MessageMiddleware',
        # X-Frame-Options 中间件
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
    ]
    

    上面的是默认的配置,关于这些中间件的功能,可以点击这里查看。

    自定义中间件

    自定义中间件有两种方法,一种是比较老的方法,另一种是在老方法的基础上的新的定义方式。

    • 老方式
      要点:
    1. 自定义一个from django.utils.deprecation.MiddlewareMixin的子类
    2. 为类写钩子函数(钩子函数如下表)
    钩子函数 执行时机 执行顺序(相对与配置列表) 参数 返回值
    process_request 请求刚到来,执行视图之前 正序 HttpRequest对象 None或者HttpResponse对象
    process_response 视图执行完毕,返回响应时 逆序 HttpRequest对象和HttpResponse对象 HttpResponse对象
    process_view process_request之后,路由转发到视图,执行视图之前 正序 HttpRequest对象, 视图函数, view args参数, view kwargs参数 None或者HttpResponse对象
    process_exception 视图执行中发生异常时 逆序 HttpRequest对象和异常类对象 None或者HttpResponse对象
    process_template_response 视图刚执行完毕,process_response之前 逆序 HttpRequest对象和TemplateResponse对象 实现了render方法的响应对象

    各个钩子函数的执行顺序

    例子:

    # app01/middlewares/miMiddleware.py
    
    from django.utils.deprecation import MiddlewareMixin
    
    
    class MyMiddleWare(MiddlewareMixin):
    
        def process_request(self, request):
            print("处理请求")
    
        def process_response(self, request, response):
            print("返回响应")
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print("在执行%s视图前" % view_func.__name__)
    
        def process_exception(self, request, exception):
            print("处理视图异常...")
    
    
    # settings.py
    
    MIDDLEWARE = [
        "app01.middlewares.myMiddleware.MyMiddleWare",
    ]
    
    • 新方式
      不需要继承MiddlewareMixin类,而且process_requestprocess_response定义__call__方法中。
    class MyMiddleWare:
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
    
            print("处理请求")
    
            response = self.get_response(request)
    
            print("返回响应")
    
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
    
            print("在执行%s视图前" %view_func.__name__)
    
        def process_exception(self,request,exception):
            print("处理视图异常...")
    		
    

    同样需要在settings配置MIDDLEWARE。

    应用实例一:IP拦截
    如果我们想限制某些IP对服务器的访问,可以在settings.py中添加一个BLACKLIST(全大写)列表,将被限制的IP地址写入其中。
    然后,我们就可以编写下面的中间件了:

    from django.http import HttpResponseForbidden
    from django.conf import settings
    
    class BlackListMiddleware():
    
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
    
            if request.META['REMOTE_ADDR'] in getattr(settings, "BLACKLIST", []):
                return HttpResponseForbidden('<h1>该IP地址被限制访问!</h1>')
    
            response = self.get_response(request)
    
            return response
    

    应用实例二:DEBUG页面
    网站上线正式运行后,我们会将DEBUG改为 False,这样更安全。但是发生服务器5xx系列错误时,管理员却不能看到错误详情,调试很不方便。有没有办法比较方便地解决这个问题呢?
    即:

    • 普通访问者看到的是500错误页面
    • 管理员看到的是错误详情Debug页面

    利用中间件就可以做到!代码如下:

    import sys
    from django.views.debug import technical_500_response
    from django.conf import settings
    
    
    class DebugMiddleware():
    
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
    
            response = self.get_response(request)
    
            return response
    
        def process_exception(self, request, exception):
            # 如果是管理员,则返回一个特殊的响应对象,也就是Debug页面
            # 如果是普通用户,则返回None,交给默认的流程处理
            if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.ADMIN_IP:
                return technical_500_response(request, *sys.exc_info())
    
    

    本文来自博客园,作者:忞翛,转载请注明原文链接:https://www.cnblogs.com/lczmx/p/14938905.html

  • 相关阅读:
    windows +xampp+wordpress
    IP 包类型
    [二叉树]已知后序/中序遍历,求先序遍历
    QT 设置应用程序图标
    Nginx 优化 Alex
    编译安装REDIS Alex
    Http简介 Alex
    Nginx调试 Alex
    利用私有CA 给内部https网站颁发证书 Alex
    实现https安全网站之自签名证书 Alex
  • 原文地址:https://www.cnblogs.com/lczmx/p/14938905.html
Copyright © 2020-2023  润新知