django 요청 에서 응답 까지 의 과정 깊이 설명

django 시작
우 리 는 django 프로젝트 를 시작 할 때 명령 행 에서 실행 하 든 pycharm 에서 직접 클릭 하여 실행 하 든 사실은'runserver'작업 을 수행 합 니 다.ruserver 는 django 가 가지 고 있 는 웹 server 를 사용 합 니 다.주로 개발 과 디 버 깅 에 사용 되 며,정식 환경 에 서 는 nginx+uwsgi 모드 를 사용 합 니 다.
어떤 방식 이 든 프로젝트 를 시작 하면 두 가지 일 을 합 니 다.
  • WSGIServer 클래스 의 인 스 턴 스 를 만 들 고 사용자 의 요청 을 받 습 니 다.
  • 사용자 의 http 요청 이 도 착 했 을 때 사용자 의 요청 과 응답 을 처리 할 WSGIHandler 를 지정 합 니 다.이 Handler 는 전체 request 를 처리 하 는 핵심 입 니 다.
  • WSGI
    WSGI:모두 웹 서버 Gateway Interface 라 고 합 니 다.WSGI 는 서버 가 아니 라 프로그램 과 상호작용 하 는 API 도 사용 하지 않 습 니 다.코드 가 아니 라 인 터 페 이 스 를 정의 하여 웹 서버 가 웹 애플 리 케 이 션 과 어떻게 통신 하 는 지 설명 하 는 규범 입 니 다.
    클 라 이언 트 가 요청 을 한 번 보 낸 후에 가장 먼저 요청 을 처리 하 는 것 은 사실상 웹 서버 입 니 다.이것 은 우리 가 자주 말 하 는 nginx,Apache 와 같은 웹 서버 입 니 다.그리고 웹 서버 는 요청 을 웹 응용 프로그램(예 를 들 어 django)에 맡 깁 니 다.이 중간 에 있 는 중 개 는 바로 WSGI 입 니 다.웹 서버 와 웹 프레임 워 크(Django)를 연결 합 니 다.

    WSGI 의 일부 내용 을 간단하게 소개 합 니 다.응용 프로그램 은 호출 가능 한 대상(함수/방법)이 라 고 규정 한 다음 에 2 개의 고정 매개 변 수 를 받 습 니 다.하 나 는 서버 엔 드 를 포함 한 환경 변수 이 고 다른 하 나 는 호출 가능 한 대상 입 니 다.이 대상 은 응답 을 초기 화하 고 응답 에 status code 상태 코드 와 httpt 머리 를 추가 하 며 호출 가능 한 대상 을 되 돌려 줍 니 다.간단 한 예 를 볼 수 있다
    
    #       python    
    def simplr_wsgi_app(environ, start_response):
     #       ,django          
     status = '200 OK'
     headers = [{'Content-type': 'text/plain'}]
     #      ,         
     start_response(status, headers)
     #        
     return ['hello world!']
    django 에서 같은 논 리 를 실현 하 는 것 은 WSGIHandler 라 는 종 류 를 통 해 다음 과 같은 것 을 중점적으로 소개 하 겠 습 니 다!
    WSGI 와 uWSGI 에 관심 이 있다 면 이 글 을 추천 합 니 다.WSGI & uwsgi,대 박!
    중간 부품 기본 개념
    말 그대로 미들웨어 는 웹 서버 와 웹 애플 리 케 이 션 사이 에 있 으 며 추가 기능 을 추가 할 수 있다.django 프로젝트(pycharm 을 통 해)를 만 들 면 필요 한 미들웨어 를 자동 으로 설정 합 니 다.
    
    MIDDLEWARE_CLASSES = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    미들웨어 는 사용자 의 데 이 터 를 예비 처리 한 다음 에 응용 프로그램 에 보 냅 니 다.응용 프로그램 이 응답 부 하 를 사용자 에 게 되 돌려 주기 전에 결과 데 이 터 를 최종 적 으로 조정 합 니 다.통속 적 으로 django 에서 중간 에 request 라 는 대상 을 준비 한 다음 에 request 대상 을 직접 사용 하여 각종 데 이 터 를 얻 을 수 있 고 response 를 머리,상태 코드 등 을 추가 할 수 있 습 니 다.
    데이터 흐름
    django 가 요청 을 받 았 을 때 WSGIHandler 를 초기 화 합 니 다.프로젝트 의 wgi.py 파일 을 추적 할 수 있 습 니 다.이 종 류 를 발견 할 수 있 습 니 다.
    
    class WSGIHandler(base.BaseHandler):
     def __call__(self, environ, start_response):
     pass
    이 종 류 는 WSGI 응용 규정 에 따라 두 개의 인 자 를 받 아들 입 니 다.하 나 는 서버 엔 드 를 포함 한 환경 변수 이 고 다른 하 나 는 호출 가능 한 대상 이 며 교체 가능 한 대상 을 되 돌려 줍 니 다.
    이 handler 는 요청 에서 응답 까지 의 전체 과정 을 제어 합 니 다.주요 프로 세 스:

    인터넷 에서 다른 그림 을 보면 더욱 완전 하 다.

    대략 몇 단계:
    1.사용자 가 브 라 우 저 를 통 해 페이지 요청 
    2.Request Middlewares 에 도착 할 것 을 요청 합 니 다.중간 부품 은 request 에 대해 미리 처리 하거나 직접 response 요청 을 합 니 다. 
    3.URLConf 는 urls.py 파일 과 요청 한 URL 을 통 해 해당 하 는 View 를 찾 습 니 다. 
    4.View Middlewares 에 접근 하면 request 를 처리 하거나 response 로 직접 돌아 갈 수 있 습 니 다. 
    5.View 의 함수 호출 
    6.View 의 방법 은 Models 를 통 해 바 텀 데이터 에 선택적으로 접근 할 수 있 습 니 다. 
    7.모든 Model-toDB 의 상호작용 은 manager 를 통 해 이 루어 집 니 다. 
    8.필요 하 다 면 뷰 는 특수 한 Context 를 사용 할 수 있 습 니 다. 
    9.Context 는 페이지 생 성 을 위해 Template 에 전 달 됩 니 다.  
        a.Template 는 Filters 와 Tags 를 사용 하여 출력 을 렌 더 링 합 니 다.  
        b.출력 이 View 로 되 돌아 가기  
        c.HTTP Response 가 Response Middlewares 에 전송 되 었 습 니 다.  
        d.모든 Response Middlewares 는 response 를 풍부하게 하거나 완전히 다른 response 를 되 돌려 줄 수 있 습 니 다.  
        e.Response 를 브 라 우 저 로 되 돌려 사용자 에 게 보 여 줍 니 다. 
    중간 클래스 의 순서 와 방법
    django 의 미들웨어 류 는 적어도 다음 과 같은 네 가지 방법 중 하 나 를 포함 하고 있 습 니 다.
    process_request、 process_view、process_exception、process_response
    WSGIHandler loadmiddleware 는 이 방법 을 각각 에 추가 합 니 다.request_middleware、_view_middleware、_response_middleware 와exception_middleware 네 개의 목록 중.
    모든 미들웨어 에 이 네 가지 방법 이 있 는 것 은 아 닙 니 다.어떤 방법 이 존재 하지 않 으 면 불 러 오 는 과정 에서 이 종 류 는 건 너 뜁 니 다.
    
    for middleware_path in settings.MIDDLEWARE_CLASSES:
     ・・・
     if hasattr(mw_instance, 'process_request'):
     request_middleware.append(mw_instance.process_request)
     if hasattr(mw_instance, 'process_view'):
     self._view_middleware.append(mw_instance.process_view)
     if hasattr(mw_instance, 'process_template_response'):
     self._template_response_middleware.insert(0, mw_instance.process_template_response)
     if hasattr(mw_instance, 'process_response'):
     self._response_middleware.insert(0, mw_instance.process_response)
     if hasattr(mw_instance, 'process_exception'):
     self._exception_middleware.insert(0, mw_instance.process_exception)
    우 리 는 소스 코드 에서 프로 세 스 request 와 프로 세 스 를 볼 수 있다.  response 의 실행 로드 순 서 는 정반 대 입 니 다.순환 중,processrequest 는 append 가 목록 의 끝 에 있 고 processrequest 는 insert 에 의 해 맨 앞 에 있 습 니 다.

    (어떤 경우 에는 Comment 미들웨어 가 Session 앞 에 있 을 수 있 습 니 다.로 딩 순 서 를 알 았 으 면 좋 겠 습 니 다)
    process_request
    중간 부품 의 예 를 몇 개 들다.
    
    class CommonMiddleware(object):
    #    
     def process_request(self, request):
    
     # Check for denied User-Agents
     if 'HTTP_USER_AGENT' in request.META:
     for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
     if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
      raise PermissionDenied('Forbidden user agent')
     host = request.get_host()
    
     if settings.PREPEND_WWW and host and not host.startswith('www.'):
     host = 'www.' + host
     pass
    CommonMiddleware 의 processrequest 는 주로 사용자 에이전트 가 요구 에 부합 되 는 지 판단 하고 URL 을 보완 하 는 것 입 니 다.예 를 들 어 ww 나 끝 에/를 추가 하 는 것 입 니 다.
    
    class SessionMiddleware(object):
     def process_request(self, request):
     session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
     request.session = self.SessionStore(session_key)
    Session Middleware 의 processrequest 는 sessionkey 는 cookies 에서 꺼 내 서 request.session 에 넣 습 니 다.
    
    class AuthenticationMiddleware(MiddlewareMixin):
     def process_request(self, request):
     assert hasattr(request, 'session'), (
      "The Django authentication middleware requires session middleware "
      "to be installed. Edit your MIDDLEWARE%s setting to insert "
      "'django.contrib.sessions.middleware.SessionMiddleware' before "
      "'django.contrib.auth.middleware.AuthenticationMiddleware'."
     ) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
     request.user = SimpleLazyObject(lambda: get_user(request))
    앞에서 말 했 듯 이 중간 부품 의 로드 는 일정한 순서(정반 서)에 따라
    Authentication Middleware 의 processrequest 방법 은 session 미들웨어 를 기반 으로 불 러 온 다음 request 의 session 을 통 해 사용 자 를 꺼 내 request.user 에 넣 습 니 다.
    process_request 는 None 또는 HTTP Response 대상 을 되 돌려 야 합 니 다.None 로 돌아 갈 때 WSGI handler 는 process 를 계속 불 러 옵 니 다.request 안의 방법,다음 상황 이 라면 Handlers 는 바로 불 러 옵 니 다response_middleware 목록,그리고 직접 response.
    해석 url
    당request_middleware 목록 의 processrequest 가 옮 겨 다 니 면 처 리 된 request 대상(request.session,request.user 등 속성 이 추가 되 었 습 니 다)을 얻 을 수 있 습 니 다.
    django 는 url 을 순서대로 정규 매 칭 합 니 다.일치 하지 않 으 면 이상 을 던 집 니 다.request 의 미들웨어 가 None 으로 돌아 가면 Django 는 사용자 가 요청 한 URL 을 분석 합 니 다.
    setting 에 ROOT 가 있어 요.URLCONF 는 urls.py 파일 을 가리 키 며 이 파일 에 따라 urlconf 를 생산 할 수 있 습 니 다.본질 적 으로 그 는 url 과 보기 함수 간 의 매 핑 표 입 니 다.그리고 resolver 를 통 해 사용자 의 url 을 분석 하여 첫 번 째 일치 하 는 view 를 찾 을 수 있 습 니 다.
    process_view
    url 의 매 칭 을 통 해 보기 함수 와 관련 된 인 자 를 얻 을 수 있 습 니 다.view 함 수 를 호출 하기 전에 django 가 먼저 불 러 옵 니 다view_middleware 의 각 processview 방법.
    기본 미들웨어 를 한 번 씩 봤 는데 csrf 에 만 이 방법 이 있 습 니 다.
    
    #    
    class CsrfViewMiddleware(object):
    
     def process_view(self, request, callback, callback_args, callback_kwargs):
    
     if getattr(request, 'csrf_processing_done', False):
      return None
    
     try:
      csrf_token = _sanitize_token(
      request.COOKIES[settings.CSRF_COOKIE_NAME])
      # Use same token next time
      request.META['CSRF_COOKIE'] = csrf_token
     except KeyError:
      csrf_token = None
     if getattr(callback, 'csrf_exempt', False):
      return None
     pass
    이 방법 은 cookiers 에 csrf 필드 가 존재 하 는 지 판단 하 는 역할 을 합 니 다.존재 하지 않 으 면 이상 을 던 지고 존재 하면 None 로 돌아 갑 니 다.
    view 미들웨어 는 requst 미들웨어 와 마찬가지 로 None 또는 httpResponse 를 되 돌려 야 합 니 다.httpresponse 를 되 돌려 주면 Handlers 는 직접 불 러 옵 니 다response_middleware 의 목록 을 HttpResponse 로 되 돌려 줍 니 다.그러면 Handlers 는 바로 불 러 옵 니 다response_middleware 목록,그리고 직접 response
    실행 뷰 논리
    view 함수 만족:
  • 함수(FBV)또는 클래스 기반(CVB)보기.
  • 에서 받 아들 인 매개 변 수 는 첫 번 째 는 request 이 고 response 대상 을 되 돌려 야 합 니 다.
  • 보기 함수 에 이상 을 던 지면 Handler 는 반복 해서exception_middleware 목록,이상 하 게 던 져 지면 뒤의 processexception 은 실행 되 지 않 습 니 다.
    process_response
    이 단계 에서 우 리 는 HTTP Response 대상 을 얻 었 습 니 다.이 대상 은 process 일 수 있 습 니 다.view 가 되 돌 아 왔 습 니 다.보기 함수 가 되 돌 아 왔 을 수도 있 습 니 다.현재 우 리 는 응답 미들웨어 에 순환 적 으로 접근 할 것 이다.이것 은 미들웨어 가 데 이 터 를 조정 할 마지막 기회 이다.예 를 들 어:
    
    class XFrameOptionsMiddleware(object):
    
     def process_response(self, request, response):
     # Don't set it if it's already in the response
     if response.get('X-Frame-Options') is not None:
      return response
    
     # Don't set it if they used @xframe_options_exempt
     if getattr(response, 'xframe_options_exempt', False):
      return response
    
     response['X-Frame-Options'] = self.get_xframe_options_value(request,
             response)
     return response
    XFrameOptions Middleware 는 X-Frame-Options 를 response 에 가입 시 켜 사이트 가 끼 워 넣 거나 납치 되 는 것 을 방지한다.
    
    class CsrfViewMiddleware(object):
     def process_response(self, request, response):
     if getattr(response, 'csrf_processing_done', False):
      return response
    
     if not request.META.get("CSRF_COOKIE_USED", False):
      return response
    
     # Set the CSRF cookie even if it's already set, so we renew
     # the expiry timer.
     response.set_cookie(settings.CSRF_COOKIE_NAME,
        request.META["CSRF_COOKIE"],
        max_age=settings.CSRF_COOKIE_AGE,
        domain=settings.CSRF_COOKIE_DOMAIN,
        path=settings.CSRF_COOKIE_PATH,
        secure=settings.CSRF_COOKIE_SECURE,
        httponly=settings.CSRF_COOKIE_HTTPONLY
        )
     # Content varies with the CSRF cookie, so set the Vary header.
     patch_vary_headers(response, ('Cookie',))
     response.csrf_processing_done = True
     return response
    CsrfView Middleware response 에 csrf cookies 설정
    마지막.
    response 의 미들웨어 가 불 러 오 면 시스템 은 돌아 오기 전에 WSGI 서버 에서 보 내 온 start 를 호출 합 니 다.response 방법 대상 은 응답 을 초기 화하 고 response 응답 을 합 니 다.
    총결산
    본문의 중점 은:
  • django 가 시 작 될 때 WSGIserver 를 시작 하고 모든 요청 한 사용자 에 게 handler 를 만 들 었 습 니 다.
  • WSGI 프로 토 콜 을 이해 하고 WSGIHandler 라 는 종 류 는 전체 요청 이 응답 하 는 절차 와 전체 절차 의 기본 과정 을 제어 합 니 다.
  • 미들웨어 의 개념 및 모든 processrequest, process_response, process_view, process_exception 방법 은 어느 단계 에서 어떤 역할 을 발휘 합 니까?
  • 중간 가격 이 실 행 될 때 순서 가 있 습 니 다.request 와 view 는 순서대로 실 행 됩 니 다.response 와 exception 은 역순 입 니 다.이 단 계 는 WSGIHandler 가 각 목록 에 불 러 올 때 이 루어 집 니 다.
  • 자,이상 이 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
    참고 블 로그:
      1, Django 튜 토리 얼 노트:6.미들웨어
      2, python 웹 개발 을 하려 면 이해 해 야 합 니 다:WSGI&uwsgi
      3, 요청 부터 응답 django 까지 어떤 처 리 를 했 습 니까?   
      4, django 는 요청 부터 복귀 까지 어떤 경험 을 했 습 니까?

    좋은 웹페이지 즐겨찾기