from rest_framework.permissions import IsAuthenticated, IsAdminUser from rest_framework.views import APIView from rest_framework.request import Request from rest_framework.response import Response from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView, RetrieveAPIView from drf_spectacular.utils import extend_schema from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters from rest_framework import status from .utils import IsProfessorOnly from .models import Publication, Rating, Category from .serializers import PublicationSerializer, AdminPublicationSerializer, RatePublicationSerializer, CategorySerializer from users.models import User from project.serializers import MessageResponseSerializer # Create your views here. @extend_schema( tags=['Publications'], methods=['GET'], summary='List publications', ) @extend_schema( tags=['Publications'], methods=['POST'], summary='Create new publication (only authorized)', ) class PublicationsAPIView(ListCreateAPIView): queryset = Publication.objects.with_related().only_publish() serializer_class = PublicationSerializer filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_fields = ['is_pinned', 'user', 'content_type', 'category'] ordering_fields = ['is_pinned', 'average_score', 'time_created', 'time_updated'] ordering = ['-time_created'] search_fields = ['user__username', 'description'] def get_permissions(self): if self.request.method == 'POST': return [IsAuthenticated()] return super().get_permissions() @extend_schema( tags=['Publications'], summary='Publication details', ) class PublicationDetailAPIView(RetrieveAPIView): queryset = Publication.objects.with_related().only_publish() serializer_class = PublicationSerializer @extend_schema( tags=['Publications'], methods=['GET'], summary='List publications (only admin or professor)', ) @extend_schema( tags=['Publications'], methods=['POST'], summary='Create new publication (only admin or professor)', ) class AdminPublicationsAPIView(PublicationsAPIView): queryset = Publication.objects.with_related() serializer_class = AdminPublicationSerializer filterset_fields = ['is_pinned', 'user', 'content_type', 'category', 'status'] ordering_fields = ['is_pinned', 'average_score', 'time_created', 'time_updated', 'status'] def get_permissions(self): return [IsProfessorOnly()] @extend_schema( tags=['Publications'], summary='CRUD for publication (only admin or professor)', ) class AdminPublicationDetailAPIView(RetrieveUpdateDestroyAPIView): queryset = Publication.objects.with_related() serializer_class = AdminPublicationSerializer permission_classes = [IsProfessorOnly] @extend_schema( tags=['Categories'], methods=['GET'], summary='List categories', ) @extend_schema( tags=['Categories'], methods=['POST'], summary='Create new category (only admin)', ) class CategoryListAPIView(ListCreateAPIView): queryset = Category.objects.all() serializer_class = CategorySerializer filter_backends = [filters.SearchFilter, filters.OrderingFilter] ordering = ['name'] search_fields = ['name'] def get_permissions(self): if self.request.method == 'POST': return [IsAdminUser] return super().get_permissions() @extend_schema( tags=['Categories'], summary='CRUD for category (only admin)', ) class CategoryDetailAPIView(RetrieveUpdateDestroyAPIView): queryset = Category.objects.all() serializer_class = CategorySerializer permission_classes = [IsAdminUser] class RatePublicationAPIView(APIView): permission_classes = [IsAuthenticated] @extend_schema( tags=['Publications'], summary='Rate publication', request=RatePublicationSerializer, responses=MessageResponseSerializer ) def post(self, request: Request, format=None): serializer = RatePublicationSerializer(data=request.data) serializer.is_valid(raise_exception=True) user: User = request.user publication = serializer.validated_data['publication'] score = serializer.validated_data['score'] Rating.rate_publication(user, publication, score) return Response( {"detail": "Rating saved successfully"}, status=status.HTTP_200_OK )