#视图函数到Response
def full_dispatch_request(self):
#调用使用before_request方法添加的一系列扩展函数,可重载自定义函数处理
self.try_trigger_before_first_request_functions()
try:
request_started.send(self) #request_started信号
rv = self.preprocess_request()#分发前调用,与蓝图相关
if rv is None:
rv = self.dispatch_request() #分发给视图函数处理
#rv就是视图函数处理的结果
except Exception as e:
rv = self.handle_user_exception(e)
#将结果传入finalize_request,封装视图函数处理结果
return self.finalize_request(rv)
def finalize_request(self, rv, from_error_handler=False):
response = self.make_response(rv) #封装response成response_class的一个实例
try:
#默认调用after_request方法添加的一系列扩展函数,可重载自定义函数处理
response = self.process_response(response)
request_finished.send(self, response=response) #发送request_finished信号
except Exception:
if not from_error_handler:
raise
self.logger.exception(
"Request finalizing failed with an error while handling an error"
)
return response
def make_response(self, rv):
"""Convert the return value from a view function to an instance of
:attr:`response_class`.
将返回值转换成Wrappers.py的response类的实例
:param rv: the return value from the view function. The view function
must return a response. Returning ``None``, or the view ending
without returning, is not allowed. The following types are allowed
for ``view_rv``:
可以返回如下类型
``str`` (``unicode`` in Python 2)#UTF-8的字符串
A response object is created with the string encoded to UTF-8
as the body.
``bytes`` (``str`` in Python 2)
A response object is created with the bytes as the body.
``dict``
A dictionary that will be jsonify'd before being returned.
``tuple``
Either ``(body, status, headers)``, ``(body, status)``, or
``(body, headers)``, where ``body`` is any of the other types
allowed here, ``status`` is a string or an integer, and
``headers`` is a dictionary or a list of ``(key, value)``
tuples. If ``body`` is a :attr:`response_class` instance,
``status`` overwrites the exiting value and ``headers`` are
extended.
:attr:`response_class`
The object is returned unchanged.
other :class:`~werkzeug.wrappers.Response` class
The object is coerced to :attr:`response_class`.
:func:`callable`
The function is called as a WSGI application. The result is
used to create a response object.
"""
status = headers = None
# unpack tuple returns #处理元组类型
if isinstance(rv, tuple):
len_rv = len(rv)
# a 3-tuple is unpacked directly
if len_rv == 3:
rv, status, headers = rv
# decide if a 2-tuple has status or headers
elif len_rv == 2:
if isinstance(rv[1], (Headers, dict, tuple, list)):
rv, headers = rv
else:
rv, status = rv
# other sized tuples are not allowed
else:
raise TypeError(
"The view function did not return a valid response tuple."
" The tuple must have the form (body, status, headers),"
" (body, status), or (body, headers)."
)
# the body must not be None 不能为空
if rv is None:
raise TypeError(
"The view function did not return a valid response. The"
" function either returned None or ended without a return"
" statement."
)
# make sure the body is an instance of the response class
if not isinstance(rv, self.response_class):
#text_type,bytes,bytearray类型直接调用response_class实例化
if isinstance(rv, (text_type, bytes, bytearray)):
# let the response class set the status and headers instead of
# waiting to do it manually, so that the class can handle any
# special logic
rv = self.response_class(rv, status=status, headers=headers)
status = headers = None
#dict类型封装
elif isinstance(rv, dict):
rv = jsonify(rv) #json/init.py里的封装方法
#BaseResponse或可调用类型处理
elif isinstance(rv, BaseResponse) or callable(rv):
# evaluate a WSGI callable, or coerce a different response
# class to the correct type
try:
rv = self.response_class.force_type(rv, request.environ)
except TypeError as e:
new_error = TypeError(
"{e}\nThe view function did not return a valid"
" response. The return type must be a string, dict, tuple,"
" Response instance, or WSGI callable, but it was a"
" {rv.__class__.__name__}.".format(e=e, rv=rv)
)
reraise(TypeError, new_error, sys.exc_info()[2])
#报错
else:
raise TypeError(
"The view function did not return a valid"
" response. The return type must be a string, dict, tuple,"
" Response instance, or WSGI callable, but it was a"
" {rv.__class__.__name__}.".format(rv=rv)
)
# prefer the status if it was provided 可自定义状态码
if status is not None:
if isinstance(status, (text_type, bytes, bytearray)):
rv.status = status
else:
rv.status_code = status
# extend existing headers with provided headers 可自定义头部
if headers:
rv.headers.extend(headers)
return rv
"""
从full_dispatch_request函数返回后
直接调用response类方法装入WSGI框架处理了(response就是Wrappers.py的response类)
"""
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)