锁定老帖子 主题:django源代码分析三 走向现代
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-11-22
response = callback(request, *callback_args, **callback_kwargs) 前两篇估计不怎么解馋——没有涉及到任何关于web开发的东西。呵呵,其实我的这些文章不是要写怎么用django,而是以一种探索的心态深入到django的内部,不断的发现它的各种扩展点,各种有用的工具。 闲言少叙,切入正题。我们要了解当一个web请求自客户端提交到服务器端,都经过了那些“磨难”。首先让我们找到这一切的根源—— django.core.management.commands.runserver.py。这个启动了django的web server。 在runserver.py的59行 handler = AdminMediaHandler(WSGIHandler(), admin_media_path) run(addr, int(port), handler) 在第59行,我们不难发现,django底层是基于WSGI的,它的application有了两个,一个是AdminMediaHandler 提供后台管理的静态页面的访问,一个是WSGIHandler,这个是最主要的,负责除实际的views分发。run函数是定义在basehttp.py 中的 def run(addr, port, wsgi_handler): server_address = (addr, port) httpd = WSGIServer(server_address, WSGIRequestHandler) httpd.set_app(wsgi_handler) httpd.serve_forever() WSGIServer和WSGIRequestHandler是django基于python HTTPServer写的一个WSGI的服务器。有兴趣的朋友可以参考一下这个http://docs.python.org/library /basehttpserver.html 这里是python内置的一些服务器实现。这些内容也够讲一阵的,这里我们就不岔开话题了。回头继续看我们的代码,WSGIHandler是“一切”的开 始,在__call__方法实际进行“分发”。 if self._request_middleware is None: self.initLock.acquire() # Check that middleware is still uninitialised. if self._request_middleware is None: self.load_middleware() self.initLock.release() 首先看到的是这个代码段,这里进行了django middleware有人翻译成中间件,我觉得这是一种只译的方式不可取;拦截器更贴切。这段代码中,首先进行了加锁,然后加载拦截器,然后释放锁;这里 加锁的目的是因为__call__是线程不安全的。我们跟进load_middleware里面,可以看到django的拦截器是如何被加载的,我们看 53行, if hasattr(mw_instance, 'process_request'): request_middleware.append(mw_instance.process_request) if hasattr(mw_instance, 'process_view'): self._view_middleware.append(mw_instance.process_view) if hasattr(mw_instance, 'process_response'): self._response_middleware.insert(0, mw_instance.process_response) if hasattr(mw_instance, 'process_exception'): self._exception_middleware.insert(0, mw_instance.process_exception) django提供了process_reuqeest、process_view、process_response、 process_exception,这几种拦截点,这比WSGI的拦截更加的细致。在django.middleware中定义了django内置的一 些拦截装置,有兴趣的朋友不妨参考一下。 signals.request_started.send(sender=self.__class__) try: try: request = self.request_class(environ) except UnicodeDecodeError: response = http.HttpResponseBadRequest() else: response = self.get_response(request) # Apply response middleware for middleware_method in self._response_middleware: response = middleware_method(request, response) response = self.apply_response_fixes(request, response) finally: signals.request_finished.send(sender=self.__class__) 注意signal这里,这个是django的另一个拦截点,这里我们看到,会发送request_started、 request_finished这两个消息,其实除了这两个,django还有一些model的消息,可以参考这里 http://docs.djangoproject.com/en/dev/topics/signals/ 最重要的是这一句 response = self.get_response(request) 这个调用了父类BaseHandler的get_response,在82句是 callback, callback_args, callback_kwargs = resolver.resolve( request.path_info) 92句 response = callback(request, *callback_args, **callback_kwargs) 我们已经看到了“希望”,92句开启了views的执行。get_response还涉及到URL的解析,有兴趣的朋友可以仔细阅读。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 4909 次