cache api responses
This commit is contained in:
parent
8d2e18c890
commit
3614e0656c
2 changed files with 45 additions and 3 deletions
41
src/c3nav/api/views/cache.py
Normal file
41
src/c3nav/api/views/cache.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.utils.cache import patch_vary_headers
|
||||||
|
|
||||||
|
from ..permissions import get_unlocked_packages
|
||||||
|
|
||||||
|
|
||||||
|
class CachedViewSetMixin:
|
||||||
|
def get_cache_key(self, request):
|
||||||
|
cache_key = ('api__' + ('OPTIONS' if request.method == 'OPTIONS' else 'GET') + '_' +
|
||||||
|
base64.b64encode(self.get_cache_params(request).encode()).decode() + '_' +
|
||||||
|
request.path + '?' + request.META['QUERY_STRING'])
|
||||||
|
return cache_key
|
||||||
|
|
||||||
|
def get_cache_params(self, request):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
do_cache = request.method in ('GET', 'HEAD', 'OPTIONS')
|
||||||
|
if do_cache:
|
||||||
|
cache_key = self.get_cache_key(request)
|
||||||
|
if cache_key in cache:
|
||||||
|
return cache.get(cache_key)
|
||||||
|
response = super().dispatch(request, *args, **kwargs)
|
||||||
|
patch_vary_headers(response, ['Cookie'])
|
||||||
|
if do_cache:
|
||||||
|
response.render()
|
||||||
|
cache.set(cache_key, response, 60)
|
||||||
|
return response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_response_headers(self):
|
||||||
|
headers = super().default_response_headers
|
||||||
|
headers['Vary'] += ', Cookie'
|
||||||
|
return headers
|
||||||
|
|
||||||
|
|
||||||
|
class AccessCachedViewSetMixin(CachedViewSetMixin):
|
||||||
|
def get_cache_params(self, request):
|
||||||
|
return super().get_cache_params(request)+'___'+'___'.join(get_unlocked_packages(request))
|
|
@ -11,9 +11,10 @@ from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||||
from ...mapdata.models import Level, Package, Source
|
from ...mapdata.models import Level, Package, Source
|
||||||
from ..permissions import filter_source_queryset
|
from ..permissions import filter_source_queryset
|
||||||
from ..serializers import LevelSerializer, PackageSerializer, SourceSerializer
|
from ..serializers import LevelSerializer, PackageSerializer, SourceSerializer
|
||||||
|
from .cache import AccessCachedViewSetMixin, CachedViewSetMixin
|
||||||
|
|
||||||
|
|
||||||
class LevelViewSet(ReadOnlyModelViewSet):
|
class LevelViewSet(CachedViewSetMixin, ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
Returns a list of all levels on the map.
|
Returns a list of all levels on the map.
|
||||||
"""
|
"""
|
||||||
|
@ -26,7 +27,7 @@ class LevelViewSet(ReadOnlyModelViewSet):
|
||||||
search_fields = ('name',)
|
search_fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
class PackageViewSet(ReadOnlyModelViewSet):
|
class PackageViewSet(AccessCachedViewSetMixin, ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
Returns a list of all packages the map consists of.
|
Returns a list of all packages the map consists of.
|
||||||
"""
|
"""
|
||||||
|
@ -39,7 +40,7 @@ class PackageViewSet(ReadOnlyModelViewSet):
|
||||||
search_fields = ('name',)
|
search_fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
class SourceViewSet(ReadOnlyModelViewSet):
|
class SourceViewSet(AccessCachedViewSetMixin, ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
Returns a list of source images (to use as a drafts).
|
Returns a list of source images (to use as a drafts).
|
||||||
Call /sources/{name}/image to get the image.
|
Call /sources/{name}/image to get the image.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue