• Django中间件初始化过程


    def load_middleware(self):
        """
        Populate middleware lists from settings.MIDDLEWARE.
    
        Must be called after the environment is fixed (see __call__ in subclasses).
        """
        self._view_middleware = []
        self._template_response_middleware = []
        self._exception_middleware = []
    
        handler = convert_exception_to_response(self._get_response) #为返回视图的函数,包一层出错函数处理异常。如果出错,返回出错的response,如果没出错,返回_get_response返回的东西
        for middleware_path in reversed(settings.MIDDLEWARE):   #从底向上遍历settings中的中间件列表
            middleware = import_string(middleware_path)
            try:
                mw_instance = middleware(handler)   #中间件实例:初始化每个中间件类,将他们的get_response初始化为,有异常处理的调用视图函数
            except MiddlewareNotUsed as exc:
                if settings.DEBUG:
                    if str(exc):
                        logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
                    else:
                        logger.debug('MiddlewareNotUsed: %r', middleware_path)
                continue
    
            if mw_instance is None:
                raise ImproperlyConfigured(
                    'Middleware factory %s returned None.' % middleware_path
                )
    
            if hasattr(mw_instance, 'process_view'):   #如果有view函数,放在类中,之后调用中间件时候使用
                self._view_middleware.insert(0, mw_instance.process_view)
            if hasattr(mw_instance, 'process_template_response'):
                self._template_response_middleware.append(mw_instance.process_template_response)
            if hasattr(mw_instance, 'process_exception'):
                self._exception_middleware.append(mw_instance.process_exception)
    
            handler = convert_exception_to_response(mw_instance)  #为初始化好的中间件实例包一层异常处理
            #每次循环,这里的handler都作为下一个中间件的get_response,也就是,每个中间件的get_response为上一个中间件实例(外面包一层异常)
    
        # We only assign to this when initialization is complete as it is used
        # as a flag for initialization being complete.
        self._middleware_chain = handler  #循环结束,chain为顶层中间件(settings中的第一个),顶层中间件实例中的get_response包了下一层中间件实例
    
    
    def _get_response(self, request):
        """
        Resolve and call the view, then apply view, exception, and
        template_response middleware. This method is everything that happens
        inside the request/response middleware.
        """
        response = None
    
        if hasattr(request, 'urlconf'):
            urlconf = request.urlconf
            set_urlconf(urlconf)
            resolver = get_resolver(urlconf)
        else:
            resolver = get_resolver()  
    
        resolver_match = resolver.resolve(request.path_info)  #从请求url获取视图
        callback, callback_args, callback_kwargs = resolver_match  #获取视图函数,以及传参
        request.resolver_match = resolver_match
    
        # Apply view middleware
        for middleware_method in self._view_middleware:
            response = middleware_method(request, callback, callback_args, callback_kwargs) #在调用视图前调用view中间件,注意,如果有一个中间件返回response,将不调用视图函数
            if response:
                break
    
        if response is None:
            wrapped_callback = self.make_view_atomic(callback)  #为每个视图封装一个事务
            try:
                response = wrapped_callback(request, *callback_args, **callback_kwargs)  #调用视图函数
            except Exception as e:
                response = self.process_exception_by_middleware(e, request)
    
        # Complain if the view returned None (a common error).   #调用视图之后返回response为空的异常处理
        if response is None:
            if isinstance(callback, types.FunctionType):    # FBV
                view_name = callback.__name__
            else:                                           # CBV
                view_name = callback.__class__.__name__ + '.__call__'
    
            raise ValueError(
                "The view %s.%s didn't return an HttpResponse object. It "
                "returned None instead." % (callback.__module__, view_name)
            )
    
        # If the response supports deferred rendering, apply template
        # response middleware and then render the response
        elif hasattr(response, 'render') and callable(response.render):
            for middleware_method in self._template_response_middleware:
                response = middleware_method(request, response)
                # Complain if the template response middleware returned None (a common error).
                if response is None:
                    raise ValueError(
                        "%s.process_template_response didn't return an "
                        "HttpResponse object. It returned None instead."
                        % (middleware_method.__self__.__class__.__name__)
                    )
    
            try:
                response = response.render()
            except Exception as e:
                response = self.process_exception_by_middleware(e, request)
    
        return response
  • 相关阅读:
    moss文档库操作的几个类
    Infopath web浏览中的多项选择功能
    国际软件项目经理的七大素质转
    InfoPath中的Rich Text Box中如何加“回车”
    设计模式——策略模式
    设计模式——状态模式
    设计模式——备忘模式
    设计模式——中介者模式
    关与BaseDataList类型绑定ArrayList
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/EmptyRabbit/p/11390299.html
Copyright © 2020-2023  润新知