Skip to content

Commit

Permalink
feat: add cache for programs list view
Browse files Browse the repository at this point in the history
  • Loading branch information
AmooHashem committed Aug 30, 2024
1 parent e41d2c0 commit 2edf6f4
Showing 1 changed file with 46 additions and 17 deletions.
63 changes: 46 additions & 17 deletions apps/fsm/views/program_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import NotFound
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from django.utils.decorators import method_decorator
from django.core.cache import cache
from django.views.decorators.cache import cache_page

from apps.fsm.models import Program
from apps.fsm.pagination import ProgramsPagination
from apps.fsm.permissions import ProgramAdminPermission

from apps.fsm.serializers.program_serializers import ProgramSerializer, ProgramSummarySerializer

from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.response import Response

from apps.accounts.serializers.user_serializer import UserSerializer
from apps.accounts.utils import find_user_in_website
from apps.fsm.utils import add_admin_to_program
Expand All @@ -28,20 +27,22 @@ class ProgramViewSet(ModelViewSet):
filterset_fields = ['website']
pagination_class = ProgramsPagination

def get_object(self):
lookup_value = self.kwargs.get('pk')
def dispatch(self, request, *args, **kwargs):
response = super().dispatch(request, *args, **kwargs)

# Try to fetch by slug first
program = self.queryset.filter(slug=lookup_value).first()
# Add headers to prevent frontend caching
response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response['Pragma'] = 'no-cache'
response['Expires'] = '0'

if program is None:
# If slug lookup fails, try ID lookup
try:
program = self.queryset.get(id=int(lookup_value))
except (ValueError, Program.DoesNotExist):
raise NotFound(
f"No Program found with slug or id: {lookup_value}")
return response

def get_object(self):
lookup_value = self.kwargs.get(self.lookup_field)
program = self.queryset.filter(slug=lookup_value).first(
) or self.queryset.filter(id=lookup_value).first()
if not program:
raise NotFound(f"No Program found with slug or id: {lookup_value}")
return program

def initialize_request(self, request, *args, **kwargs):
Expand Down Expand Up @@ -107,4 +108,32 @@ def soft_delete(self, request, pk=None):
program.is_deleted = True
program.deleted_at = timezone.now()
program.save()
self.invalidate_list_cache()
return Response()

@method_decorator(cache_page(60 * 15))
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

def create(self, request, *args, **kwargs):
response = super().create(request, *args, **kwargs)
self.invalidate_list_cache()
return response

def update(self, request, *args, **kwargs):
response = super().update(request, *args, **kwargs)
self.invalidate_list_cache()
return response

def partial_update(self, request, *args, **kwargs):
response = super().partial_update(request, *args, **kwargs)
self.invalidate_list_cache()
return response

def invalidate_list_cache(self):
cache_key = self.get_list_cache_key()
cache.delete(cache_key)

def get_list_cache_key(self):
# This should match the key used by cache_page
return f'program-view-set.{self.request.path}'

0 comments on commit 2edf6f4

Please sign in to comment.