73 lines
3.4 KiB
Python
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)
|