最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Django中间件的介绍和使用

    正文概述    2020-07-10   296

    Django中间件的介绍和使用

    中间件是 Django 用来处理请求和响应的钩子框架。它是一个轻量级的、底层级的“插件”系统,用于全局性地控制Django 的输入或输出,可以理解为内置的app或者小框架。

    在django.core.handlers.base模块中定义了如何接入中间件,这也是学习Django源码的入口之一。

    每个中间件组件负责实现一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话机制将用户与请求request关联起来。

    中间件可以放在你的工程的任何地方,并以Python路径的方式进行访问。

    Django 具有一些内置的中间件,并自动开启了其中的一部分,我们可以根据自己的需要进行调整。

    一、如何启用中间件

    若要启用中间件组件,请将其添加到 Django 配置文件settings.py的 MIDDLEWARE 配置项列表中。

    在 MIDDLEWARE 中,中间件由字符串表示。这个字符串以圆点分隔,指向中间件工厂的类或函数名的完整 Python 路径。下面是使用 django-admin startproject命令创建工程后,默认的中间件配置:

    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中可以不使用任何中间件,如果你愿意的话,MIDDLEWARE 配置项可以为空。但是强烈建议至少使用 CommonMiddleware。而笔者的建议是保持默认的配置,这有助于你提高网站的安全性。

    二、 中间件最关键的顺序问题

    MIDDLEWARE 的顺序很重要,具有先后关系,因为有些中间件会依赖其他中间件。例如: AuthenticationMiddleware 需要在会话中间件中存储的经过身份验证的用户信息,因此它必须在 SessionMiddleware 后面运行 。

    在请求阶段,调用视图之前,Django 按照定义的顺序执行中间件 MIDDLEWARE,自顶向下。

    你可以把它想象成一个洋葱:每个中间件类都是一个“皮层”,它包裹起了洋葱的核心--实际业务视图。如果请求通过了洋葱的所有中间件层,一直到内核的视图,那么响应将在返回的过程中以相反的顺序再通过每个中间件层,最终返回给用户。

    如果某个层的执行过程认为当前的请求应该被拒绝,或者发生了某些错误,导致短路,直接返回了一个响应,那么剩下的中间件以及核心的视图函数都不会被执行。

    三、Django内置的中间件

    Django内置了下面这些中间件,满足了我们一般的需求:

    Cache

    缓存中间件

    如果启用了该中间件,Django会以CACHE_MIDDLEWARE_SECONDS 配置的参数进行全站级别的缓存。

    Common

    通用中间件

    该中间件为我们提供了一些便利的功能:

    禁止DISALLOWED_USER_AGENTS中的用户代理访问服务器

    自动为URL添加斜杠后缀和www前缀功能。如果配置项 APPEND_SLASH 为True ,并且访问的URL 没有斜杠后缀,在URLconf中没有匹配成功,将自动添加斜杠,然后再次匹配,如果匹配成功,就跳转到对应的url。 PREPEND_WWW 的功能类似。

    为非流式响应设置Content-Length头部信息。

    作为展示的例子,这里额外贴出它的源代码,位于django.middleware.common模块中,比较简单,很容易读懂和理解:

    class CommonMiddleware(MiddlewareMixin):
        """    去掉了doc    """
        response_redirect_class = HttpResponsePermanentRedirect
    
        def process_request(self, request):
            # Check for denied User-Agents
            if 'HTTP_USER_AGENT' in request.META:
                for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                    if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                        raise PermissionDenied('Forbidden user agent')
    
            # Check for a redirect based on settings.PREPEND_WWW
            host = request.get_host()
            must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
            redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''
    
            # Check if a slash should be appended
            if self.should_redirect_with_slash(request):
                path = self.get_full_path_with_slash(request)
            else:
                path = request.get_full_path()
    
            # Return a redirect if necessary
            if redirect_url or path != request.get_full_path():
                redirect_url += path
                return self.response_redirect_class(redirect_url)
    
        def should_redirect_with_slash(self, request):
    
            if settings.APPEND_SLASH and not request.path_info.endswith('/'):
                urlconf = getattr(request, 'urlconf', None)
                return (
                    not is_valid_path(request.path_info, urlconf) and
                    is_valid_path('%s/' % request.path_info, urlconf)
                )
            return False
    
        def get_full_path_with_slash(self, request):
    
            new_path = request.get_full_path(force_append_slash=True)
            if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):
                raise RuntimeError(
                    "You called this URL via %(method)s, but the URL doesn't end "
                    "in a slash and you have APPEND_SLASH set. Django can't "
                    "redirect to the slash URL while maintaining %(method)s data. "
                    "Change your form to point to %(url)s (note the trailing "
                    "slash), or set APPEND_SLASH=False in your Django settings." % {
                        'method': request.method,
                        'url': request.get_host() + new_path,
                    }
                )
            return new_path
    
        def process_response(self, request, response):
            # If the given URL is "Not Found", then check if we should redirect to
            # a path with a slash appended.
            if response.status_code == 404:
                if self.should_redirect_with_slash(request):
                    return self.response_redirect_class(self.get_full_path_with_slash(request))
    
            if settings.USE_ETAGS and self.needs_etag(response):
                warnings.warn(
                    "The USE_ETAGS setting is deprecated in favor of "
                    "ConditionalGetMiddleware which sets the ETag regardless of "
                    "the setting. CommonMiddleware won't do ETag processing in "
                    "Django 2.1.",
                    RemovedInDjango21Warning
                )
                if not response.has_header('ETag'):
                    set_response_etag(response)
    
                if response.has_header('ETag'):
                    return get_conditional_response(
                        request,
                        etag=response['ETag'],
                        response=response,
                    )
            # Add the Content-Length header to non-streaming responses if not
            # already set.
            if not response.streaming and not response.has_header('Content-Length'):
                response['Content-Length'] = str(len(response.content))
    
            return response
    
        def needs_etag(self, response):
            """Return True if an ETag header should be added to response."""
            cache_control_headers = cc_delim_re.split(response.get('Cache-Control', ''))
            return all(header.lower() != 'no-store' for header in cache_control_headers)

    起源地下载网 » Django中间件的介绍和使用

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元