48 lines
1.4 KiB
Python
Executable file
48 lines
1.4 KiB
Python
Executable file
from inspect import signature
|
|
from django.core.cache import cache
|
|
from django.db.models.query import QuerySet
|
|
|
|
import hashlib
|
|
|
|
MAX_NUM_CHAR = 15
|
|
|
|
|
|
def cache_wrapper(prefix, timeout=86400):
|
|
def arg_to_str(arg):
|
|
if hasattr(arg, "id"):
|
|
return str(arg.id)
|
|
if isinstance(arg, list) or isinstance(arg, QuerySet):
|
|
return hashlib.sha1(str(list(arg)).encode()).hexdigest()[:MAX_NUM_CHAR]
|
|
if len(str(arg)) > MAX_NUM_CHAR:
|
|
return str(arg)[:MAX_NUM_CHAR]
|
|
return str(arg)
|
|
|
|
def get_key(func, *args, **kwargs):
|
|
args_list = list(args)
|
|
signature_args = list(signature(func).parameters.keys())
|
|
args_list += [kwargs.get(k) for k in signature_args[len(args) :]]
|
|
args_list = [arg_to_str(i) for i in args_list]
|
|
key = prefix + ":" + ":".join(args_list)
|
|
key = key.replace(" ", "_")
|
|
return key
|
|
|
|
def decorator(func):
|
|
def wrapper(*args, **kwargs):
|
|
cache_key = get_key(func, *args, **kwargs)
|
|
result = cache.get(cache_key)
|
|
if result is not None:
|
|
return result
|
|
|
|
result = func(*args, **kwargs)
|
|
cache.set(cache_key, result, timeout)
|
|
return result
|
|
|
|
def dirty(*args, **kwargs):
|
|
cache_key = get_key(func, *args, **kwargs)
|
|
cache.delete(cache_key)
|
|
|
|
wrapper.dirty = dirty
|
|
|
|
return wrapper
|
|
|
|
return decorator
|