You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

188 lines
6.3 KiB

from rest_framework.generics import ListAPIView, RetrieveAPIView
from django.db.models import Count, Q, F
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework.exceptions import NotFound
from rest_framework.permissions import IsAuthenticated
from rest_framework.filters import SearchFilter
from apps.course.serializers import (
CourseListSerializer, CourseCategorySerializer, CourseDetailSerializer,
AttachmentSerializer, GlossarySerializer, MyCourseListSerializer
)
from apps.course.models import Course, CourseCategory, Attachment, Glossary, Participant
from apps.course.doc import *
class CourseCategoryAPIView(ListAPIView):
queryset = CourseCategory.objects.all()
serializer_class = CourseCategorySerializer
@swagger_auto_schema(
operation_description=doc_course_category(),
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
class CourseListAPIView(ListAPIView):
queryset = Course.objects.all().exclude(status=Course.StatusChoices.INACTIVE)
serializer_class = CourseListSerializer
filter_backends = [SearchFilter]
search_fields = ['title']
@swagger_auto_schema(
operation_description=doc_course_list(),
manual_parameters=[
openapi.Parameter(
'category_slug', openapi.IN_QUERY,
description="Category of the Course",
type=openapi.TYPE_STRING,
enum=[category.slug for category in CourseCategory.objects.all()]
),
openapi.Parameter(
'status', openapi.IN_QUERY,
type=openapi.TYPE_STRING,
description="""Status =>
Upcoming (visible but registration not allowed)---Предстоящие
Registering (registration is open)---регистрация
Ongoing (course has started, registration closed)---Впроцессе
Finished (course has ended)---закончился
""",
enum=[status for status in ['upcoming', 'registering', 'ongoing', 'finished']]
),
openapi.Parameter(
'is_free', openapi.IN_QUERY,
description="Ценообразование is_free <bool>",
type=openapi.TYPE_BOOLEAN,
),
openapi.Parameter(
'is_online', openapi.IN_QUERY,
description="Статус участия is_online <bool>",
type=openapi.TYPE_BOOLEAN,
),
])
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = super().get_queryset()
request = self.request
filters = request.query_params
if category := filters.get('category_slug'):
queryset = queryset.filter(category__slug=category)
if status := filters.get('status'):
queryset = queryset.filter(status=status)
if is_free := filters.get('is_free'):
is_free = is_free.lower() == 'true'
queryset = queryset.filter(
models.Q(is_free=is_free) | models.Q(price=0) if is_free else models.Q(is_free=False, price__gt=0)
)
if is_online := filters.get('is_online'):
is_online = is_online.lower() == 'true'
queryset = queryset.filter(is_online=is_online)
return queryset
class CourseDetailAPIView(RetrieveAPIView):
queryset = Course.objects.all()
serializer_class = CourseDetailSerializer
lookup_field = "slug"
@swagger_auto_schema(
operation_description=doc_course_detail(),
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
class MyCourseListAPIView(ListAPIView):
serializer_class = MyCourseListSerializer
permission_classes = [IsAuthenticated]
@swagger_auto_schema(manual_parameters=[
openapi.Parameter(
'completed', openapi.IN_QUERY,
description="мои курсы completed <bool> true",
type=openapi.TYPE_BOOLEAN,
),
],
operation_description=doc_courses_my_courses(),
operation_summary="Home",
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = Course.objects.all()
request = self.request
filters = request.query_params
student = self.request.user
qs = queryset.filter(participants__student=student)
completed_only = filters.get('completed', '').lower() == 'true'
if completed_only:
queryset = queryset.annotate(
total_lessons=Count('lessons', distinct=True),
completed_lessons=Count(
'lessons__completions',
filter=Q(lessons__completions__student=student),
distinct=True
)
).filter(total_lessons=F('completed_lessons'))
return queryset
class AttachmentListAPIView(ListAPIView):
serializer_class = AttachmentSerializer
@swagger_auto_schema(
manual_parameters=[
openapi.Parameter(
'slug', openapi.IN_PATH,
description="Slug of the Course",
type=openapi.TYPE_STRING,
required=True
)
],
operation_description="Retrieve a list of attachments for a given course by its slug."
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
course_slug = self.kwargs.get('slug')
try:
course = Course.objects.get(slug=course_slug)
except Course.DoesNotExist:
raise NotFound("Course not found")
return Attachment.objects.filter(course=course)
class GlossaryListAPIView(ListAPIView):
serializer_class = GlossarySerializer
filter_backends = [SearchFilter]
search_fields = ['title', 'description']
def get_queryset(self):
course_slug = self.kwargs.get('slug')
try:
course = Course.objects.get(slug=course_slug)
except Course.DoesNotExist:
raise NotFound("Course not found")
return Glossary.objects.filter(course=course)