132 lines
4.4 KiB
Python

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
)