def api_etag(permissions=True, etag_func=AccessPermission.etag_func, cache_parameters=None):
def wrapper(func):
@wraps(func)
def wrapped_func(self, request, *args, **kwargs):
response_format = self.perform_content_negotiation(request)[0].format
etag_user = (':'+str(request.user.pk or 0)) if response_format == 'api' else ''
raw_etag = '%s%s:%s:%s' % (response_format, etag_user, get_language(),
(etag_func(request) if permissions else MapUpdate.current_cache_key()))
etag = quote_etag(raw_etag)
response = get_conditional_response(request, etag=etag)
if response is None:
cache_key = 'mapdata:api:'+request.path_info[5:].replace('/', '-').strip('-')+':'+raw_etag
if cache_parameters is not None:
for param, type_ in cache_parameters.items():
value = int(param in request.GET) if type_ == bool else type_(request.GET.get(param))
cache_key += ':'+urlsafe_base64_encode(str(value).encode()).decode()
data = cache.get(cache_key)
if data is not None:
response = Response(data)
if response is None:
response = func(self, request, *args, **kwargs)
if cache_parameters is not None and response.status_code == 200:
cache.set(cache_key, response.data, 300)
response['ETag'] = etag
response['Cache-Control'] = 'no-cache'
return response
return wrapped_func
return wrapper
评论列表
文章目录