장고 미들웨어 이해하기
Django의 요청 처리 과정에서 미들웨어는 중요한 역할을 합니다. 이 문서에서는 미들웨어의 기본 개념과 사용 방법에 대해 설명합니다.
기본 미들웨어 설정
Django 설정 파일에는 MIDDLEWARE 리스트가 있으며, 여기에 여러 문자열이 포함되어 있습니다. 각 문자열은 특정 미들웨어 클래스를 가리킵니다. 예를 들어, POST 요청을 간단하게 처리하려면 일부 미들웨어를 주석 처리해야 할 수 있습니다.
요청이 들어올 때 미들웨어는 상위부터 하위로 request를 처리하고, 응답이 나갈 때는 하위부터 상위로 response를 처리합니다.
미들웨어 구조
미들웨어 클래스 구조
미들웨어 클래스는 다음과 같은 구조를 따릅니다:
- MiddlewareMixin 클래스를 상속받습니다.
from django.utils.deprecation import MiddlewareMixin
- 초기화 함수
__init__를 정의할 수 있습니다. process_request와process_response메서드를 구현합니다.
process_request는 request 객체를 인자로 받으며 반환 값이 없습니다.process_response는 request와 response 객체를 인자로 받으며, 반드시 response 객체를 반환해야 합니다.
사용자 정의 미들웨어
다음은 사용자 정의 미들웨어를 작성하는 방법입니다:
from django.utils.deprecation import MiddlewareMixin
class CustomMiddleware(MiddlewareMixin): def process_request(self, req): pass
def process_response(self, req, resp):
return resp
이 클래스를 MIDDLEWARE 리스트에 등록하면 됩니다.
미들웨어 실행 순서
process_request와 process_response 메서드의 실행 순서는 중요합니다. 요청 시 미들웨어는 상위에서 하위로, 응답 시 하위에서 상위로 실행됩니다.
process_request가 HttpResponse 객체를 반환하면 해당 미들웨어의process_response가 즉시 호출됩니다.process_response의 반환 값은 다음 단계의 미들웨어로 전달됩니다.
문자열 리스트를 통한 미들웨어 등록
미들웨어를 문자열 리스트로 등록하는 원리는 두 가지 핵심 개념을 이해해야 합니다:
importlib 모듈
importlib 모듈을 사용하면 문자열을 통해 모듈을 동적으로 로드할 수 있습니다.
import importlib
mod = importlib.import_module('myapp.middleware')
cls = getattr(mod, 'MyMiddleware')
obj = cls()
모듈 객체의 리플렉션
모듈 내의 클래스나 함수를 동적으로 접근할 수 있습니다.
attr = getattr(aaa, 'func')
attr()
미들웨어 등록 예제
MIDDLEWARE_LIST = [
'myapp.middleware.MiddlewareOne',
'myapp.middleware.MiddlewareTwo',
]
def execute_middlewares(request):
for path in MIDDLEWARE_LIST:
module_path, cls_name = path.rsplit('.', 1)
module = importlib.import_module(module_path)
cls = getattr(module, cls_name)
obj = cls()
obj.process_request(request)
사용자 정의 미들웨어 추가
사용자 정의 미들웨어를 작성하는 기본적인 단계는 다음과 같습니다:
- 미들웨어 클래스를 저장할 Python 파일을 생성합니다.
- MiddlewareMixin을 상속받는 클래스를 작성하고 필요한 메서드를 구현합니다.
- MIDDLEWARE 리스트에 클래스 경로를 등록합니다.
일반적인 미들웨어 메서드
process_request
- 이 메서드는 요청을 처리하며, 요청이 라우팅되기 전에 실행됩니다.
- request 객체를 인자로 받아 요청을 처리하고 HttpResponse 객체를 반환할 수 있습니다.
process_response
- 이 메서드는 응답을 처리하며, 뷰에서 응답이 반환된 후 실행됩니다.
- request와 response 객체를 인자로 받아 응답을 수정하고 반드시 response 객체를 반환해야 합니다.
기타 메서드
process_view: 라우팅 이후, 뷰 함수/클래스 실행 전에 호출됩니다.process_exception: 뷰에서 예외가 발생했을 때 호출됩니다.process_template_response: 뷰에서 템플릿 응답을 반환할 때 호출됩니다.
이러한 정보를 바탕으로 Django의 전체 요청 처리 흐름도를 그릴 수 있습니다.