parent
289737ed00
commit
dd802dccbb
@ -1,146 +0,0 @@ |
|||||||
from functools import wraps, WRAPPER_ASSIGNMENTS |
|
||||||
|
|
||||||
from django.http.response import HttpResponse |
|
||||||
|
|
||||||
from common.cache.storage import AppDownloadShortShowCache |
|
||||||
|
|
||||||
|
|
||||||
def get_cache(alias): |
|
||||||
from django.core.cache import caches |
|
||||||
return caches[alias] |
|
||||||
|
|
||||||
|
|
||||||
def set_short_show_cache(short, cache_key): |
|
||||||
short_show_cache = AppDownloadShortShowCache("ShortDownloadView".lower(), short) |
|
||||||
key_list = short_show_cache.get_storage_cache() |
|
||||||
|
|
||||||
if key_list and isinstance(key_list, list): |
|
||||||
key_list.append(cache_key) |
|
||||||
key_list = list(set(key_list)) |
|
||||||
else: |
|
||||||
key_list = [cache_key] |
|
||||||
short_show_cache.set_storage_cache(key_list, 600) |
|
||||||
|
|
||||||
|
|
||||||
class CacheResponse: |
|
||||||
""" |
|
||||||
Store/Receive and return cached `HttpResponse` based on DRF response. |
|
||||||
.. note:: |
|
||||||
This decorator will render and discard the original DRF response in |
|
||||||
favor of Django's `HttpResponse`. The allows the cache to retain a |
|
||||||
smaller memory footprint and eliminates the need to re-render |
|
||||||
responses on each request. Furthermore it eliminates the risk for users |
|
||||||
to unknowingly cache whole Serializers and QuerySets. |
|
||||||
""" |
|
||||||
|
|
||||||
def __init__(self, |
|
||||||
timeout=None, |
|
||||||
key_func=None, |
|
||||||
cache=None, |
|
||||||
cache_errors=None): |
|
||||||
if timeout is None: |
|
||||||
self.timeout = None |
|
||||||
else: |
|
||||||
self.timeout = timeout |
|
||||||
|
|
||||||
if key_func is None: |
|
||||||
self.key_func = '' |
|
||||||
else: |
|
||||||
self.key_func = key_func |
|
||||||
|
|
||||||
if cache_errors is None: |
|
||||||
self.cache_errors = True |
|
||||||
else: |
|
||||||
self.cache_errors = cache_errors |
|
||||||
|
|
||||||
self.cache = get_cache(cache or 'default') |
|
||||||
|
|
||||||
def __call__(self, func): |
|
||||||
this = self |
|
||||||
|
|
||||||
@wraps(func, assigned=WRAPPER_ASSIGNMENTS) |
|
||||||
def inner(self, request, *args, **kwargs): |
|
||||||
return this.process_cache_response( |
|
||||||
view_instance=self, |
|
||||||
view_method=func, |
|
||||||
request=request, |
|
||||||
args=args, |
|
||||||
kwargs=kwargs, |
|
||||||
) |
|
||||||
|
|
||||||
return inner |
|
||||||
|
|
||||||
def process_cache_response(self, |
|
||||||
view_instance, |
|
||||||
view_method, |
|
||||||
request, |
|
||||||
args, |
|
||||||
kwargs): |
|
||||||
|
|
||||||
key = self.calculate_key( |
|
||||||
view_instance=view_instance, |
|
||||||
view_method=view_method, |
|
||||||
request=request, |
|
||||||
args=args, |
|
||||||
kwargs=kwargs |
|
||||||
) |
|
||||||
|
|
||||||
timeout = self.calculate_timeout(view_instance=view_instance) |
|
||||||
|
|
||||||
response_triple = self.cache.get(key) |
|
||||||
if not response_triple: |
|
||||||
# render response to create and cache the content byte string |
|
||||||
response = view_method(view_instance, request, *args, **kwargs) |
|
||||||
response = view_instance.finalize_response(request, response, *args, **kwargs) |
|
||||||
response.render() |
|
||||||
|
|
||||||
if not response.status_code >= 400 or self.cache_errors: |
|
||||||
# django 3.0 has not .items() method, django 3.2 has not ._headers |
|
||||||
if hasattr(response, '_headers'): |
|
||||||
headers = response._headers.copy() |
|
||||||
else: |
|
||||||
headers = {k: (k, v) for k, v in response.items()} |
|
||||||
response_triple = ( |
|
||||||
response.rendered_content, |
|
||||||
response.status_code, |
|
||||||
headers |
|
||||||
) |
|
||||||
short = kwargs.get("short", '') |
|
||||||
set_short_show_cache(short, key) |
|
||||||
self.cache.set(key, response_triple, timeout) |
|
||||||
else: |
|
||||||
# build smaller Django HttpResponse |
|
||||||
content, status, headers = response_triple |
|
||||||
response = HttpResponse(content=content, status=status) |
|
||||||
for k, v in headers.values(): |
|
||||||
response[k] = v |
|
||||||
if not hasattr(response, '_closable_objects'): |
|
||||||
response._closable_objects = [] |
|
||||||
|
|
||||||
return response |
|
||||||
|
|
||||||
def calculate_key(self, |
|
||||||
view_instance, |
|
||||||
view_method, |
|
||||||
request, |
|
||||||
args, |
|
||||||
kwargs): |
|
||||||
if isinstance(self.key_func, str): |
|
||||||
key_func = getattr(view_instance, self.key_func) |
|
||||||
else: |
|
||||||
key_func = self.key_func |
|
||||||
return key_func( |
|
||||||
view_instance=view_instance, |
|
||||||
view_method=view_method, |
|
||||||
request=request, |
|
||||||
args=args, |
|
||||||
kwargs=kwargs, |
|
||||||
) |
|
||||||
|
|
||||||
def calculate_timeout(self, view_instance, **_): |
|
||||||
if isinstance(self.timeout, str): |
|
||||||
self.timeout = getattr(view_instance, self.timeout) |
|
||||||
return self.timeout |
|
||||||
|
|
||||||
|
|
||||||
cache_response = CacheResponse |
|
Loading…
Reference in new issue