[Django] 원본 해석 Django 시작 및 접근 프로세스 (4)
15404 단어 Django는 입문부터 정통까지.
Django 방문 과정 (1) 에서 우리는 요청 내용이 django에 들어갔다는 것을 알게 되었다.core.handlers.wsgi.WSGIHandler.__call__처리를 진행하고, 다음은 우리가 이어서 원본 코드를 계속 해석할 것이다.
django.core.handlers.wsgi.WSGIHandler.call
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# django 。
self.load_middleware()
def __call__(self, environ, start_response):
#
set_script_prefix(get_script_name(environ))
# requet
# runserver , ‘django.core.management.base.BaseCommand’ ,
# BaseCommand 'from django.db import DEFAULT_DB_ALIAS, connections' ,
# db.__init__.py request_started 。
'''
# , reset_queries
signals.request_started.connect(reset_queries)
# , close_old_connections
signals.request_started.connect(close_old_connections)
# , close_old_connections
signals.request_finished.connect(close_old_connections)
'''
signals.request_started.send(sender=self.__class__, environ=environ)
# WSGIRequest request, request 。
request = self.request_class(environ)
#
# request
# response
response = self.get_response(request)
# get_response
'''
def get_response(self, request):
"""Return an HttpResponse object for the given HttpRequest."""
# Setup default url resolver for this thread
set_urlconf(settings.ROOT_URLCONF)
# __call__
#
response = self._middleware_chain(request)
response._closable_objects.append(request)
if response.status_code >= 400:
log_response(
'%s: %s', response.reason_phrase, request.path,
response=response,
request=request,
)
return response
'''
# :
'''
class MiddlewareMixin:
def __init__(self, get_response=None):
# load_middleware() ,
# django.core.handlers.base.BaseHandler._get_response
self.get_response = get_response
super().__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
# process_request ,
# request
# response
response = self.process_request(request)
# requets django.core.handlers.base.BaseHandler._get_response
# ,
# ,
# requset、 process_view ,
# response render ,
# response process_template_response , ;
# response , process_exception , 。
response = response or self.get_response(request)
if hasattr(self, 'process_response'):
# request response process_response ,
response = self.process_response(request, response)
# response
return response
'''
# django.core.handlers.base.BaseHandler._get_respons
'''
def _get_response(self, request):
"""
Resolve and call the view, then apply view, exception, and
template_response middleware. This method is everything that happens
inside the request/response middleware.
"""
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
# Apply view middleware
# process_viewf
for middleware_method in self._view_middleware:
response = middleware_method(request, callback, callback_args, callback_kwargs)
if response:
break
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)
# Complain if the view returned None (a common error).
if response is None:
if isinstance(callback, types.FunctionType): # FBV
view_name = callback.__name__
else: # CBV
view_name = callback.__class__.__name__ + '.__call__'
raise ValueError(
"The view %s.%s didn't return an HttpResponse object. It "
"returned None instead." % (callback.__module__, view_name)
)
# If the response supports deferred rendering, apply template
# response middleware and then render the response
# process_template_response ,
elif hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
# Complain if the template response middleware returned None (a common error).
if response is None:
raise ValueError(
"%s.process_template_response didn't return an "
"HttpResponse object. It returned None instead."
% (middleware_method.__self__.__class__.__name__)
)
try:
#
response = response.render()
except Exception as e:
response = self.process_exception_by_middleware(e, request)
return response
'''
response._handler_class = self.__class__
#
status = '%d %s' % (response.status_code, response.reason_phrase)
#
response_headers = [
*response.items(),
*(('Set-Cookie', c.output(header='')) for c in response.cookies.values()),
]
# TCPServer WSGIRequestHandler ,
# ServerHandler,
# ServerHandler run socket wsgiref.handlers.BaseHandler.start_response WSGIHandler __call__,
# header ,status
start_response(status, response_headers)
# wsgiref.handlers.BaseHandler.start_response
'''
def start_response(self, status, headers,exc_info=None):
"""'start_response()' callable as specified by PEP 3333"""
if exc_info:
try:
if self.headers_sent:
# Re-raise original exception if headers sent
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
finally:
exc_info = None # avoid dangling circular ref
elif self.headers is not None:
raise AssertionError("Headers already set!")
self.status = status
self.headers = self.headers_class(headers)
status = self._convert_string_type(status, "Status")
assert len(status)>=4,"Status must be at least 4 characters"
assert status[:3].isdigit(), "Status message must begin w/3-digit code"
assert status[3]==" ", "Status message must have a space after code"
if __debug__:
for name, val in headers:
name = self._convert_string_type(name, "Header name")
val = self._convert_string_type(val, "Header value")
assert not is_hop_by_hop(name),\
f"Hop-by-hop header, '{name}: {val}', not allowed"
return self.write
'''
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)
# response django.core.servers.basehttp.ServerHandler.run self.result,
# self.finish_response() self.wfile 。
return response
이를 통해 알 수 있듯이django의 방문 과정은 다음과 같다.
Created with Rapha l 2.2.0 클라이언트 (브라우저) 가 TCP 요청을 시작하여 TCPServer가 WSGIRequestHandler를 감청하도록 요청합니다.handle ServerHandler.run WSGIHandler.__call__ WSGIRequest 봉인 Request가 중간부품에 전달되는processrequest에서response를 가져오시겠습니까?중간부품에 Request와response를 건네주는 프로세스response response 처리 후 self.wfile는 클라이언트에게 루트가 일치하는 보기 함수에 따라 중간부품에 전달하는processview가 구체적인 보기 함수에 전달됩니까?응답 내용에 템플릿을 렌더링해야 합니까?중간부품에 넘기는 프로세스template_response를 구체적인render 방법에 맡기면 렌더링이 제대로 실행됩니까?리퀘스트와response를 중간부품에 넘기는process 로 되돌아오기response response 처리 후 self.wfile은 클라이언트에게 중간부품에 건네주는processexception 중간부품에 맡긴 프로세스exception yes no yes no yes no yes no
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Django] 원본 해석 Django 시작 및 접근 프로세스 (4)Django 액세스 프로세스(둘) Django 방문 과정 (1) 에서 우리는 요청 내용이 django에 들어갔다는 것을 알게 되었다.core.handlers.wsgi.WSGIHandler.__call__처리를 진행하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.