Django 3.x버전을 최신 4.1버전으로 update하면서 기존 Django버전에 dependency한 library들도 같이 update했다.
그러면서 여러가서 호환문제가 발생했는데 그중에 하나가
request.is_ajax가 3.X이상에서 deprecated되면서 AttributeError: 'WSGIRequest' object has no attribute 'is_ajax' 에러 발생하는 것이다.
그래서 기존 sns인증 처리 모듈에서 사용하던 is_ajax는 어떻게 대체했는지 소스를 봤더니
/Lib/site-packages/allauth/account/adapter.py
버전업전 : django-allauth 0.41.0
def is_ajax(self, request):
return request.is_ajax()
버전업후 : django-allauth 0.51.0
def is_ajax(self, request):
return any(
[
request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest",
request.content_type == "application/json",
request.META.get("HTTP_ACCEPT") == "application/json",
]
)
위 와같이 ajax호출 여부를 판단하고 있었다.
문제는 기존 소스에 있는 is_ajax부분을 어떻게 대체할 것인가 인데... 유틸성함수로 하지않고, Django의 middleware로 해결하는 방법을 찾았다.
settings.py
MIDDLEWARE = [
...
'Blog.middleware.CustomMiddleware',
...
]
Blog/middleware.py
# https://docs.djangoproject.com/en/4.1/topics/http/middleware/#middleware
class CustomMiddleware:
# Called once at startup
def __init__(self, get_response):
self.get_response = get_response
# Called every time on request
def __call__(self, request):
def is_ajax(self):
return any(
[
request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest",
request.content_type == "application/json",
request.META.get("HTTP_ACCEPT") == "application/json",
]
)
request.is_ajax = is_ajax.__get__(request)
response = self.get_response(request)
return response
이렇게 하면 request호출시 마다 __call__이 호출되면서 request객체에 is_ajax이름의 callable한 함수를 넣어 준다.
그렇게 되면 기존 소스상 아래와 같이 사용하던 부분은 수정없이 그대로 사용할 수 있다.
if request.is_ajax():
callable한 객체함수 사용법 참조 : https://blog.daonelab.com/post/11/1847/