Files
GNX-WEB/backEnd/case_studies/views.py
Iliyan Angelov 366f28677a update
2025-11-24 03:52:08 +02:00

139 lines
5.3 KiB
Python

from rest_framework import viewsets, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django_filters.rest_framework import DjangoFilterBackend
from django.db.models import Q
from .models import CaseStudy, CaseStudyCategory, Client
from .serializers import (
CaseStudyListSerializer,
CaseStudyDetailSerializer,
CaseStudyCategorySerializer,
ClientSerializer
)
class CaseStudyPagination(PageNumberPagination):
"""Custom pagination for case studies"""
page_size = 9
page_size_query_param = 'page_size'
max_page_size = 100
class CaseStudyViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for case studies
Supports filtering by category, client, and search
"""
queryset = CaseStudy.objects.filter(published=True)
pagination_class = CaseStudyPagination
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_fields = ['category__slug', 'client', 'featured']
search_fields = ['title', 'description', 'excerpt']
ordering_fields = ['published_at', 'views_count', 'created_at', 'display_order']
ordering = ['display_order', '-published_at']
lookup_field = 'slug'
def get_serializer_class(self):
if self.action == 'retrieve':
return CaseStudyDetailSerializer
return CaseStudyListSerializer
def get_queryset(self):
queryset = super().get_queryset()
# Filter by category
category_slug = self.request.query_params.get('category', None)
if category_slug and category_slug != 'all':
queryset = queryset.filter(category__slug=category_slug)
# Filter by client
client_slug = self.request.query_params.get('client', None)
if client_slug:
queryset = queryset.filter(client__slug=client_slug)
# Search query
search = self.request.query_params.get('search', None)
if search:
queryset = queryset.filter(
Q(title__icontains=search) |
Q(description__icontains=search) |
Q(excerpt__icontains=search)
)
return queryset.distinct()
def retrieve(self, request, *args, **kwargs):
"""Override retrieve to increment view count"""
instance = self.get_object()
instance.increment_views()
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(detail=False, methods=['get'])
def featured(self, request):
"""Get featured case studies"""
featured_case_studies = self.get_queryset().filter(featured=True)[:6]
serializer = self.get_serializer(featured_case_studies, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'])
def latest(self, request):
"""Get latest case studies"""
limit = int(request.query_params.get('limit', 6))
latest_case_studies = self.get_queryset()[:limit]
serializer = self.get_serializer(latest_case_studies, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'])
def popular(self, request):
"""Get popular case studies by views"""
limit = int(request.query_params.get('limit', 6))
popular_case_studies = self.get_queryset().order_by('-views_count')[:limit]
serializer = self.get_serializer(popular_case_studies, many=True)
return Response(serializer.data)
@action(detail=True, methods=['get'])
def related(self, request, slug=None):
"""Get related case studies for a specific case study"""
case_study = self.get_object()
related_case_studies = self.get_queryset().filter(
category=case_study.category
).exclude(id=case_study.id)[:4]
serializer = self.get_serializer(related_case_studies, many=True)
return Response(serializer.data)
class CaseStudyCategoryViewSet(viewsets.ReadOnlyModelViewSet):
"""ViewSet for case study categories"""
queryset = CaseStudyCategory.objects.filter(is_active=True)
serializer_class = CaseStudyCategorySerializer
lookup_field = 'slug'
@action(detail=False, methods=['get'])
def with_case_studies(self, request):
"""Get categories that have published case studies"""
categories = self.get_queryset().filter(case_studies__published=True).distinct()
serializer = self.get_serializer(categories, many=True)
return Response(serializer.data)
class ClientViewSet(viewsets.ReadOnlyModelViewSet):
"""ViewSet for clients"""
queryset = Client.objects.filter(is_active=True)
serializer_class = ClientSerializer
lookup_field = 'slug'
@action(detail=True, methods=['get'])
def case_studies(self, request, slug=None):
"""Get all case studies for a specific client"""
client = self.get_object()
case_studies = CaseStudy.objects.filter(client=client, published=True)
page = self.paginate_queryset(case_studies)
if page is not None:
serializer = CaseStudyListSerializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = CaseStudyListSerializer(case_studies, many=True)
return Response(serializer.data)