Skip to content

Instantly share code, notes, and snippets.

@allieus
Created August 4, 2020 01:30
Show Gist options
  • Save allieus/1f8fae7922f9daa60a0ccfada210fdf8 to your computer and use it in GitHub Desktop.
Save allieus/1f8fae7922f9daa60a0ccfada210fdf8 to your computer and use it in GitHub Desktop.
장고 POST 요청에서 캐싱을 삭제하는 cache_page 장식자 예시

질문 요약) cache_page를 활용하여 뷰 캐싱을 했는 데, 해당 뷰에 대해 POST 요청이 올 때 관련 캐싱을 자동 삭제하고 싶으시다는 거죠?

답변

장고 기본의 cache_page 장식자는 GET/HEAD 요청에 대해서 캐싱 로직을 동작시키며, 그 이외의 요청 (POST, PUT 등) 에 대해서는 특별한 처리를 하지 않습니다.

cache_page 장식자는 timeout 이 지난 후에 expire 되며, expire time 전에 캐싱을 삭제할려면 low level cache api로 cache key 문자열을 직접 조합하여 삭제하여야만 합니다.

cache_page 장식자는 내부적으로 CacheMiddleware를 사용하며, CacheMiddleware에 주요 로직들이 구현되어있습니다. 다음과 같이 CacheMiddleware를 상속받아 POST 요청 시에 관련 캐시를 삭제토록 구현해볼 수 있습니다.

이제 expire timeout 전이라도 POST 요청 시에 관련 캐시가 자동 삭제가 됩니다. :-)

Ask Company with Django/React

from django.middleware.cache import CacheMiddleware
from django.utils.cache import get_cache_key
from django.utils.decorators import decorator_from_middleware_with_args
class PostDeleterCacheMiddleware(CacheMiddleware):
def process_request(self, request):
if request.method == 'POST':
# https://github.com/django/django/blob/3.0.9/django/middleware/cache.py#L137
cache_key = get_cache_key(request, self.key_prefix, 'GET', cache=self.cache)
self.cache.delete(cache_key)
return super().process_request(request)
def post_deleter_cache_page(timeout, *, cache=None, key_prefix=None):
return decorator_from_middleware_with_args(PostDeleterCacheMiddleware)(
page_timeout=timeout, cache_alias=cache, key_prefix=key_prefix,
)
import datetime
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .decorators import post_deleter_cache_page
@csrf_exempt
@post_deleter_cache_page(60)
def index(request):
return HttpResponse(f"Hello World : {datetime.datetime.now()}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment