django源码分析 请求流程
2019-04-11 10:28:54来源:博客园 阅读 ()
一、从浏览器发出一个请求,到返回响应内容,这个过程是怎么样的?
1. 浏览器解析输入的url
2. 查找url对应的ip地址
3. 通过ip地址访问我们的服务器
1. 请求进入wsgi服务器(我在这里省略了可能存在的代理服务器,比如nginx)
2. wsgi服务器将请求包装后,传递给django应用
3. django应用根据请求路径找到相应的处理函数进行处理
4. 处理完成后,django应用将响应返回给wsgi服务器
5. wsgi服务器将django应用返回的响应包装后,返回响应
4. 服务器返回响应内容,浏览器渲染输出
二、django应用程序的处理入口
wsgi服务通过wsgi协议和django应用进行通信,wsgi服务是server端,django应用是application,server端通过django提供的application_callable函数去调用djano应用,application_callable函数处理完成后,将响应返回给server
django的application_callable函数在django.core.handlers.wsgi.py文件中,server服务端处理每个请求时会调用WSGIHandler这个类
#wsgi.py文件
class WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.load_middleware() def __call__(self, environ, start_response): set_script_prefix(get_script_name(environ)) signals.request_started.send(sender=self.__class__, environ=environ) request = self.request_class(environ) response = self.get_response(request) response._handler_class = self.__class__ status = '%d %s' % (response.status_code, response.reason_phrase) response_headers = list(response.items()) for c in response.cookies.values(): response_headers.append(('Set-Cookie', c.output(header=''))) start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response
三、django处理请求流程
WSGIHandler类在初始化时,首先加载中间件,将要请求的函数 _get_response用中间件封装起来(中间件相当于装饰器),执行的时候,中间件就会执行
# wsgi.py文件
def load_middleware(self): ...
self._view_middleware = [] self._template_response_middleware = [] self._exception_middleware = [] handler = convert_exception_to_response(self._get_response) for middleware_path in reversed(settings.MIDDLEWARE): middleware = import_string(middleware_path) try: mw_instance = middleware(handler) except MiddlewareNotUsed as exc: ...
handler = convert_exception_to_response(mw_instance) self._middleware_chain = handler
接下来,就是请求调用WSGIHandler
1. 实例化一个request_class
2. 通过get_response获取请求,get_response最终会调用被中间件封装后的函数 _get_response
def _get_response(self, request): 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) callback, callback_args, callback_kwargs = resolver_match request.resolver_match = resolver_match ... 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) ... return response
_get_response函数中,首先会根据url找到要调用的视图函数 resolver_match = resolver.resolve(request.path_info),然后调用视图函数 response = wrapped_callback(request, *callback_args, **callback_kwargs)返回response(在_get_response里面也是会调用一些的中间件的)
至此再将response返回给server,整个请求流程完毕
四、总结
django对于一个请求,主要过程就是寻找请求对应的视图函数,调用被中间件封装后的视图函数,返回响应。
原文链接:https://www.cnblogs.com/time-read/p/10650988.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Django项目中使用qq第三方登录。 2019-08-13
- python多线程同步实例分析 2019-08-13
- Django和前端用ajax传输json等数据 2019-08-13
- Django基本知识 2019-08-13
- JavaScript获取Django模板中指定键值的数据,使用过滤器 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash