from django.shortcuts import get_object_or_404 from drf_spectacular.utils import OpenApiResponse, extend_schema from rest_framework import viewsets from rest_framework.exceptions import PermissionDenied from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated from apps.announcements.models import Announcement from apps.courses.api.permissions import IsCourseOwner, IsTeacher from apps.courses.models import Course, CourseStatus from apps.enrollments.api.permissions import IsStudent from apps.enrollments.models import Enrollment from .serializers import AnnouncementSerializer, AnnouncementWriteSerializer @extend_schema(tags=["announcements"]) class InstructorAnnouncementViewSet(viewsets.ModelViewSet): """Instructor CRUD over announcements on their own courses.""" permission_classes = [IsAuthenticated, IsTeacher, IsCourseOwner] queryset = Announcement.objects.all().select_related("course", "posted_by") filterset_fields = ["course"] ordering = ["-created_at"] def get_queryset(self): return super().get_queryset().filter(course__instructor=self.request.user) def get_serializer_class(self): if self.action in {"create", "update", "partial_update"}: return AnnouncementWriteSerializer return AnnouncementSerializer def perform_create(self, serializer): course = serializer.validated_data["course"] if course.instructor_id != self.request.user.id: raise PermissionDenied("You don't own this course.") announcement = serializer.save(posted_by=self.request.user) # Record activity event for the instructor's home feed from apps.enrollments.models import ActivityKind from apps.enrollments.services.events import record_event record_event( course=course, actor=self.request.user, kind=ActivityKind.ANNOUNCEMENT_POSTED.value, payload={ "announcement_id": announcement.pk, "preview": (announcement.body or "")[:120], }, ) class MyCourseAnnouncementsView(ListAPIView): """Student-facing list: announcements for a specific course the student is enrolled in.""" permission_classes = [IsAuthenticated, IsStudent] serializer_class = AnnouncementSerializer pagination_class = None @extend_schema( tags=["announcements"], summary="My course announcements", description="Lists all announcements posted by the instructor on a course the student is enrolled in.", responses={ 200: AnnouncementSerializer(many=True), 403: OpenApiResponse(description="Not enrolled."), 404: OpenApiResponse(description="Course not found or not published."), }, ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): slug = self.kwargs["slug"] course = get_object_or_404(Course, slug=slug, status=CourseStatus.PUBLISHED) if not Enrollment.objects.filter(student=self.request.user, course=course).exists(): raise PermissionDenied("You are not enrolled in this course.") return ( Announcement.objects .filter(course=course) .select_related("posted_by") .order_by("-created_at") )