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.
171 lines
6.8 KiB
171 lines
6.8 KiB
from django.contrib.auth import get_user_model
|
|
from django.db.models import Count, Q
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from rest_framework.filters import SearchFilter
|
|
from rest_framework.generics import ListAPIView, RetrieveAPIView
|
|
from rest_framework.permissions import AllowAny
|
|
from drf_yasg import openapi
|
|
from drf_yasg.utils import swagger_auto_schema
|
|
|
|
from apps.course.models import Course
|
|
from apps.course.serializers import (
|
|
CourseListSerializer,
|
|
ProfessorDetailSerializer,
|
|
ProfessorListSerializer,
|
|
)
|
|
|
|
|
|
UserModel = get_user_model()
|
|
|
|
|
|
class ProfessorListAPIView(ListAPIView):
|
|
permission_classes = [AllowAny]
|
|
serializer_class = ProfessorListSerializer
|
|
filter_backends = [SearchFilter]
|
|
search_fields = ['fullname', 'email']
|
|
|
|
@swagger_auto_schema(
|
|
operation_description='دریافت فهرست استادها به همراه تعداد دورهها و درسهای فعال هر استاد.',
|
|
responses={
|
|
200: openapi.Response(
|
|
description='فهرست صفحهبندیشدهی استادها.',
|
|
schema=ProfessorListSerializer(many=True),
|
|
examples={
|
|
'application/json': {
|
|
'count': 1,
|
|
'next': None,
|
|
'previous': None,
|
|
'results': [
|
|
{
|
|
'id': 7,
|
|
'slug': 'dr-rahimi',
|
|
'fullname': 'دکتر رحیمی',
|
|
'experience_years': 10,
|
|
'course_count': 4,
|
|
'lesson_count': 56,
|
|
}
|
|
],
|
|
}
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return (
|
|
UserModel.objects.filter(user_type=UserModel.UserType.PROFESSOR)
|
|
.annotate(
|
|
course_count=Count('courses', distinct=True),
|
|
lesson_count=Count('courses__lessons', filter=Q(courses__lessons__is_active=True), distinct=True),
|
|
)
|
|
.order_by('fullname')
|
|
)
|
|
|
|
|
|
class ProfessorDetailAPIView(RetrieveAPIView):
|
|
permission_classes = [AllowAny]
|
|
serializer_class = ProfessorDetailSerializer
|
|
lookup_field = 'slug'
|
|
|
|
@swagger_auto_schema(
|
|
operation_description='دریافت جزئیات یک استاد بر اساس اسلاگ.',
|
|
responses={
|
|
200: openapi.Response(
|
|
description='اطلاعات کامل استاد.',
|
|
schema=ProfessorDetailSerializer(),
|
|
examples={
|
|
'application/json': {
|
|
'id': 7,
|
|
'device_id': 'abc-123',
|
|
'fcm': None,
|
|
'fullname': 'دکتر رحیمی',
|
|
'avatar': None,
|
|
'email': 'rahimi@example.com',
|
|
'phone_number': '+989121234567',
|
|
'password': None,
|
|
'info': 'متخصص فیزیک پزشکی.',
|
|
'skill': 'فیزیک، تدریس آنلاین',
|
|
'city': 'تهران',
|
|
'country': 'ایران',
|
|
'birthdate': '1985-04-12',
|
|
'gender': 'male',
|
|
'slug': 'dr-rahimi',
|
|
'experience_years': 10,
|
|
'course_count': 4,
|
|
'lesson_count': 56,
|
|
}
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return UserModel.objects.filter(user_type=UserModel.UserType.PROFESSOR).annotate(
|
|
course_count=Count('courses', distinct=True),
|
|
lesson_count=Count('courses__lessons', filter=Q(courses__lessons__is_active=True), distinct=True),
|
|
)
|
|
|
|
|
|
class ProfessorCourseListAPIView(ListAPIView):
|
|
permission_classes = [AllowAny]
|
|
serializer_class = CourseListSerializer
|
|
filter_backends = [SearchFilter]
|
|
search_fields = ['title', 'category__name']
|
|
|
|
@swagger_auto_schema(
|
|
operation_description='دریافت فهرست دورههای فعال یک استاد مشخصشده با اسلاگ.',
|
|
responses={
|
|
200: openapi.Response(
|
|
description='فهرست صفحهبندیشدهی دورهها.',
|
|
schema=CourseListSerializer(many=True),
|
|
examples={
|
|
'application/json': {
|
|
'count': 1,
|
|
'next': None,
|
|
'previous': None,
|
|
'results': [
|
|
{
|
|
'id': 42,
|
|
'title': 'فیزیک پایه',
|
|
'slug': 'basic-physics',
|
|
'participant_count': 150,
|
|
'category': {
|
|
'name': 'علوم پایه',
|
|
'slug': 'basic-science',
|
|
'course_count': 12,
|
|
},
|
|
'thumbnail': None,
|
|
'is_online': True,
|
|
'online_link': 'https://example.com/live/basic-physics',
|
|
'level': 'beginner',
|
|
'duration': '12h',
|
|
'lessons_count': 24,
|
|
'short_description': 'مروری بر مفاهیم پایه فیزیک.',
|
|
'status': 'published',
|
|
'is_free': False,
|
|
'price': '250000',
|
|
'discount_percentage': 20,
|
|
'final_price': '200000',
|
|
}
|
|
],
|
|
}
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
slug = self.kwargs.get('slug')
|
|
professor = get_object_or_404(UserModel.objects.filter(user_type=UserModel.UserType.PROFESSOR, slug=slug))
|
|
return Course.objects.select_related('category', 'professor').prefetch_related(
|
|
'lessons__lesson',
|
|
'lessons__completions',
|
|
'participants__student',
|
|
).exclude(status=Course.StatusChoices.INACTIVE).filter(professor=professor)
|