3 回答

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
簡單的例子:
def Base:
def _get_data(self):
# get the data eg from database
return self._get_data_native()
def get(self, request, *args, **kwargs):
return Response(self._get_data())
def Cacheable(Base):
def _get_data(self):
# get from cache ...
result = ...
if result is None:
# or from base ...
result = ...
return result
def Derived(Cacheable):
def _get_data_native(self):
# get the data eg from database
...
通過從 Cacheable 繼承,您可以在此處包含緩存,因?yàn)樵诖颂巁get_data被覆蓋。
對于這個(gè)問題,如果您只想在一個(gè)地方添加緩存,則不需要元類或裝飾器。
當(dāng)然,裝飾器可用于以更通用的方式包含緩存。

TA貢獻(xiàn)1880條經(jīng)驗(yàn) 獲得超4個(gè)贊
答案是一個(gè)裝飾器和一些Django特定的庫。
from django.utils.decorators import method_decorator
from django.core.cache import cache
def cached_get(cache_key_func=None):
"""
Decorator to be applied via django.utils.decorators.method_decorator
Implements content-aware cache fetching by decorating the "get" method
on a django View
:param cache_key_func: a function of fn(request, *args, **kwargs) --> String
which determines the cache key for the request
"""
def decorator(func):
def cached_func(request, *args, **kwargs):
assert cache_key_func is not None, "cache_key_function is required"
key = cache_key_func(request, *args, **kwargs)
result = cache.get(key)
if result is None:
return func(request, *args, **kwargs)
return Response(result)
return cached_func
return decorator
@method_decorator(cached_get(cache_key_func=get_cache_key), name="get")
class SomeView(BaseView):
...
def get_cache_key(request):
# do arbitrary processing on request, the following is the na?ve melody
key = urllib.urlencode(request.query_params)
return key
因此,解決方案是使用 Django 的內(nèi)置method_decorator函數(shù),將其第一個(gè)參數(shù)裝飾器應(yīng)用于裝飾類的方法,該方法由第二個(gè)參數(shù)name, to命名method_decorator。我定義了一個(gè)高階函數(shù),cached_get,它接受另一個(gè)函數(shù)作為它的參數(shù),并返回一個(gè)柯里化函數(shù)(閉包,所謂的)。通過調(diào)用這個(gè)函數(shù)get_cache_key(而不是,請注意,調(diào)用該函數(shù)),我有一個(gè)裝飾器,它將應(yīng)用于 .get 方法SomeView。
裝飾器本身是一個(gè)簡單的 Python 裝飾器——在這個(gè)應(yīng)用程序中,它是cached_func,而原始的、未裝飾的get方法是func。因此,cached_func內(nèi)容替換SomeView.get,所以當(dāng)SomeView.get被調(diào)用時(shí),它首先檢查緩存,但回落到未命中未修飾方法。
我希望這種方法能夠在通用適用性與內(nèi)容感知密鑰派生之間取得平衡。
添加回答
舉報(bào)