django-groupcache/groupcache/middleware.py

73 lines
3.4 KiB
Python

from django.middleware.cache import CacheMiddleware
from groupcache.core import logger, \
get_view_name, get_local_key, get_local_prefix, bump_local_prefix
from groupcache.utils import _bumping_cache
#-------------------------------------------------------------------------------
class CacheWithLocalVersionMiddleware(CacheMiddleware):
def __init__(self, group = None, view_func = None,
vary_on_view = True, *args, **kwargs):
super(CacheWithLocalVersionMiddleware, self).__init__(*args, **kwargs)
self.base_key_prefix = self.key_prefix
self.group = group
view_name = get_view_name(view_func)
self.view_name = view_name if vary_on_view is True else None
_bumping_cache[view_name] = (group, vary_on_view)
#logger.debug('Bumping: %s', repr(_bumping_cache))
def _update_key_prefix(self, view_keywords):
self.key_prefix = get_local_prefix(
get_local_key(
self.group, view_keywords,
self.view_name, self.base_key_prefix),
self.base_key_prefix)
#logger.debug('Key prefix: %s' % repr(self.key_prefix))
def process_response(self, request, response):
# See process_view()
return response
def process_request(self, request):
# See process_view()
pass
def process_view(self, request, view_func, view_args, view_keywords):
# This middleware is a derivated from CacheMiddleware:
#
# we move cache action from process_request() to and process_response(),
# because we might need to compute the group key from
# the view keywords.
if len(view_args) != 0:
raise TypeError(
'locally versionned view should exclusively use keywords')
self._update_key_prefix(view_keywords)
response = super(CacheWithLocalVersionMiddleware,
self).process_request(request)
if response is not None:
logger.debug('page found in cache')
return response
else:
# The per-view decorator we will get out of this middleware (using
# django.utils.decorators.decorator_from_middleware) behaves
# slightly differently than a fully-fledged middleware. The official
# doc states (Django 1.2, 1.3):
#
# Unlike the process_request() and process_view() methods, the
# process_response() method is always called, even if the
# process_request() and process_view() methods of the same
# middleware class were skipped because an earlier middleware method
# returned an HttpResponse (this means that your process_response()
# method cannot rely on setup done in process_request(), for
# example)
#
# This does not hold for the derivated decorators: in this case,
# process_response() is only called if process_view() returns
# nothing, and it's safe to share states between the two methods (go
# read django.utils.decorators.make_middleware_decorator).
response = view_func(request, *view_args, **view_keywords)
#logger.debug('Caching! %s' % repr(self.key_prefix)
return super(CacheWithLocalVersionMiddleware,
self).process_response(request, response)