视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
django源码分析之请求流程
2020-11-27 14:11:10 责编:小采
文档


Django 项目是一个Python定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。本文将对django的请求流程进行源码分析。

一、从浏览器发出一个请求,到返回响应内容,这个过程是怎么样的?

1. 浏览器解析输入的url

2. 查找url对应的ip地址

3. 通过ip地址访问我们的服务器

  a. 请求进入wsgi服务器(我在这里省略了可能存在的代理服务器,比如nginx)

  b. wsgi服务器将请求包装后,传递给django应用

  c. django应用根据请求路径找到相应的处理函数进行处理

  d. 处理完成后,django应用将响应返回给wsgi服务器

  e. 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文件
# 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对于一个请求,主要过程就是寻找请求对应的视图函数,调用被中间件封装后的视图函数,返回响应。

【推荐课程:Django视频教程】

下载本文
显示全文
专题