众所周知,django项目启动命令:python manage.py runserver
那么,执行runserver命令之后到底django做了哪些事情呢(uWSGI
运行Django
项目也一样)?
1、首先,django执行runserver.Command(BaseCommand)中的execute()函数。
2、execute()通过self.handle(*args, **options)来调用runserver.Command.inner_run()方法。在inner_run()方法中又做了两件事情:
至此,django项目已启动,并且实现了端口监听,那么一个请求的到来django又是如何处理的呢?
1、首先,WSGIServer实例会监听到一个请求的到来,WSGIServer通过set_app
方法设置一个可调用(callable)
的对象作为application,
并负责创建一个WSGIRequestHandler实例对象,并使用其handler()方法来处理请求(其实最终是调用wsgiref.handlers.BaseHandler
中的run
方法处理,唯一参数为application可调用对象,也就是
WSGIHandler处理器对象)。
2、至此,我们通过run(WSGIHandler)才真正进入了django世界,WSGIHandler则真正作为django处理请求与生成响应的对象。
3、回头再看WSGIHandler实例对象,由django.core.handlers.wsgi.WSGIHandler实例化而来,源码如下:
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super(WSGIHandler, self).__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 = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
start_response(force_str(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
WSGIHandler首先调用它自己的load_middleware
方法,加载所有列在MIDDLEWARE_CLASSES
中的middleware
类并且内省它们。
当这个WSGIHandler实例对象被调用时,会进入__call__方法。
现在处理器已经准备好真正开始处理了,因此它给调度程序发送一个信号request_started
(Django
内部的调度程序允许各种不同的组件声明它们正在干什么,并可以写一些代码监听特定的事件。关于这一点目前还没有官方的文档,但在wiki上有一些注释),接下来它实例化一个django.http.HttpRequest
的子类。
根据不同的处理器,可能是django.core.handlers.modpython.ModPythonRequest
的一个实例,也可能是django.core.handlers.wsgi.WSGIRequest
的一个实例。需要两个不同的类是因为mod_python
和WSGI APIs
以不同的格式传入request
信息,这个信息需要解析为Django
能够处理的一个单独的标准格式。
一旦一个HttpRequest
或者类似的东西存在了,处理器就调用它自己的get_response
方法,传入这个HttpRequest
作为唯一的参数。这里就是几乎所有真正的活动发生的地方。
4、Middleware开始工作了!
get_response
做的第一件事就是遍历处理器的_request_middleware
实例变量并调用其中的每一个方法,传入HttpRequest
的实例作为参数。
关于Middleware详细的执行流程,请参考 django中间件解析
5、处理器下一步会尝试解析请求的URL
。它在配置文件中寻找一个叫做ROOT_URLCONF
的配置,用这个配置加上根/
,作为参数来创建django.core.urlresolvers.RegexURLResolver
的一个实例,然后调用它的resolve
方法来解析请求的URL
路径。
6、一旦知道了所需的 view function
和相关的参数,处理器就会查看它的_view_middleware
列表,并调用其中的方法,传入 HttpRequst,view function
,针对这个view
的位置参数列表和关键字参数字典。
7、进入View了!
如果处理过程这时候还在继续的话,处理器会调用view function
。一般来说,views
会使用Django
的database API
来创建、检索、更新和删除数据库的某些东西,还会加载并渲染一个模板来呈现一些东西给最终用户。
8、view中有异常!
发生了异常,那么get_response
将遍历它的_exception_middleware
实例变量并调用那里的每个方法,传入HttpResponse
和这个exception
作为参数。如果顺利,这些方法中的一个会实例化一个HttpResponse
并返回它。
9、至此,django已经完成了接收一个请求,并生成响应返回给客户端。