django框架在正式环境中的请求处理流程分析

先推荐一个个人认为更好的:http://www.jianshu.com/p/679dee0a4193
django程序在正式环境中往往是通过wsgi程序去启动的,所以运行开始的入口就是django项目的wsgi.py ,这个文件的重点就是调用get_wsgi_application函数

def get_wsgi_application():

"""

The public interface to Django's WSGI support. Should return a WSGI

callable.

Allows us to avoid making django.core.handlers.WSGIHandler public API, in

case the internal WSGI implementation changes or moves in the future.

"""

django.setup(set_prefix=False)

return WSGIHandler()

函数获取一个UWSGIhandler对象,这个UWSGIhandler是一个符合UWSGI协议的对象,这个协议就是自己必须有一个call方法,这个call方法必须要有两个参数,一个environ参数,这个是web服务器传递过来的参数字典,包括环境变量; 还有一个start_response函数去处理http的请求。

这个UWSGIhanler在初始化函数init中去调用load_middleware去装载在settings里面的middleware,其实这些middleware都是一个类,最后会被实例化然后调用,同时这个对象有一个call函数,每来一个url请求,都会去调用UWSGIhandler对象,触发call函数去执行后续流程,这个推测可以在django自身的manage.py runserver分析中可以得到验证,代码如下:


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)

try:

request = self.request_class(environ)

print "request.COOKIES: ", request.COOKIES

print "request.HTTP_AUTHORIZATION: ", request.META.get('HTTP_AUTHORIZATION','No HTTP_AUTHORIZATION')

except UnicodeDecodeError:

logger.warning(

'Bad Request (UnicodeDecodeError)',

exc_info=sys.exc_info(),

extra={

'status_code': 400,

}

)

response = http.HttpResponseBadRequest()

else:

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)

print "type(response), response: ", type(response), response

#        print "response.cookies: ", response.items()[0][1]

#        print "response.headers: ", response._headers

return response

而最终UWSGI服务器会调去处理UWSGIhandler,下面代码中的application就是UWSGIhandler的实例

class BaseHandler:

def run(self, application):

    """Invoke the application"""

    # Note to self: don't move the close()!  Asynchronous servers shouldn't

    # call close() from finish_response(), so if you close() anywhere but

    # the double-error branch here, you'll break asynchronous servers by

    # prematurely closing.  Async servers must return from 'run()' without

    # closing if there might still be output to iterate over.

    try:

        self.setup_environ()

        self.result = application(self.environ, self.start_response)

上面的self.result = application(self.environ, self.start_response)就是调用application实例,从而触发call,这里的application就是

get_uwsgi_application的返回,也就是WSGIhandler的实例对象)。

从WSGIhanler对象中的call中可以看出,首先去构造一个request请求,这个request对象中的信息(主要是在view 函数中用到的信息)都是来自call函数的参数environment,猜测是http客户端传过来的请求信息。初始化好request后,就开始调用get_response()构造要返回的response了。

get_response()中调用了_middleware_chain(request)函数,其实就是调用了_get_response()函数,_get_response函数是处理关键,所以,往下看_get_response函数就好了。

_get_response函数首先做url匹配,即调用resolver.resolve(request.path_info),获得callback,callback其实就是与url匹配的view(视图函数),最后调用视图函数处理request,在_get_response中你可以看到,

for middleware_method in self._view_middleware: #self._view_middleware是在load_middleware函数里面被赋值的。

response = middleware_method(request, callback, callback_args, callback_kwargs)

if response:

break

首先判断middleware_method是否处理了request并返回了response,如果返回了response,那么就不会走到与url匹配的视图函数,也就是下面这段代码:

if response is None: #这里response为 None的情况就是 view_middleware没又返回response对象。

wrapped_callback = self.make_view_atomic(callback) #这一步使视图事务化,因为视图的处理很可能涉及到数据库操作

try:

response = wrapped_callback(request, *callback_args, **callback_kwargs) #真正调用视图函数去处理request请求,也就到了我们自己写的django业务了,即我们自己写的view

except Exception as e:

response = self.process_exception_by_middleware(e, request)

从代码中可以看出,如果response为None,也就是middleware没有返回response,那么就交由我们自己写的view函数去处理。我们自己写的django业务的主要作用是处理我们需要的逻辑,然后将结果封装成一个HttpResponse对象返回。

推荐一个写的更清晰的文章:http://www.jianshu.com/p/679dee0a4193
借用一张图备份:

django框架在正式环境中的请求处理流程分析_第1张图片
image.png

你可能感兴趣的:(django框架在正式环境中的请求处理流程分析)